7

I have a button which I give a color, image and text like this:

android:background="@color/green"
android:drawableLeft="@drawable/custom_routes_start_button_icon"
android:text="@string/custom_route_start"

This is the unselected state and want the selected state to be something like this:

android:background="@color/red"
android:drawableLeft="@drawable/custom_routes_stop_button_icon"
android:text="@string/custom_route_stop"

For all I know its not possible to give an item in selector a text or drawableLeft (only drawable). Does anybody know a nice way to achieve this? Maybe another xml file where te selector could refer too?

bsiamionau
  • 8,099
  • 4
  • 46
  • 73
Mark Molina
  • 5,057
  • 8
  • 41
  • 69

4 Answers4

6

I'm not sure if ToggleButton(or even checkbox) would fit your use case. You can indeed use selector for your drawable(left,right,top,bottom), use a background with selctor and even different text for your two states.

In effect you can define a selector one for your background (/res/color/custom_color.xml)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/green"
          android:state_checked="true" />
    <item android:color="@color/red"
        android:state_checked="false"/>
 </selector>

and one for your drawableLeft(/res/drawable/custom_drawable.xml).

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/custom_routes_start_button_icon"
          android:state_checked="true" />
    <item android:drawable="@color/custom_routes_stop_button_icon"
        android:state_checked="false"/>
 </selector>

and finally your ToggleButton definition as

android:background="@color/custom_color"
android:drawableLeft="@drawable/custom_drawable"
android:textOn="@string/custom_route_start"
android:textOff="@string/custom_route_stop"

You might have to play with styles to make it appear as you want.

Though this is a late answer,hope someone finds it useful.

jaga
  • 753
  • 11
  • 18
3

You should use two Buttons and only ever show one of them. Use android:visibility in XML and setVisibility() to show/hide the buttons.

So, at first make the start button visible and hide the stop button. When the user presses the start button, hide the start button and show the stop button. When the user presses the stop button, hide it and show the start button again.

Ridcully
  • 23,362
  • 7
  • 71
  • 86
  • Oke thanks for the answer. Thats easy to understand but never thought this was the best way to tackle such kind of problem. – Mark Molina Mar 19 '13 at 10:02
  • 1
    It is :-) The StateSelector drawables are only meant to display different states of one button, e.g. pressed, inactive, etc. but what you want are clearly two buttons. In one of my apps I have exactly what you want - a start and a stop button that are displayed alternately. So I know what I'm talking about ;-) – Ridcully Mar 19 '13 at 10:27
1

you can change this by code:

write below code in xml file:

 android:background="@color/green"
 android:drawableLeft="@drawable/custom_routes_start_button_icon"
 android:text="@string/custom_route_start" 

and on buttonClick event:

    yourButton = (TextView) findViewById(R.id.yourButton);

    yourButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Drawable checkImg = getApplicationContext().getResources().getDrawable(
                       R.drawable.custom_routes_stop_button_icon);
            yourButton.setCompoundDrawablesWithIntrinsicBounds(checkImg, null, null,
            null);
            yourButton.setBackgroundColor(red);
            yourButton.setText(custom_route_stop);
        }
    });

you can also place this code onTouchlistener:

 yourButton.setOnTouchListener(new OnTouchListener() {
        boolean isTouch = false;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                Drawable checkImg = getApplicationContext().getResources().getDrawable(
                       R.drawable.custom_routes_stop_button_icon);
                yourButton.setCompoundDrawablesWithIntrinsicBounds(checkImg, null, null, null);
                yourButton.setBackgroundColor(red);
                yourButton.setText(custom_route_stop);  
            }
            else {
                Drawable checkImg = getApplicationContext().getResources().getDrawable(
                       R.drawable.custom_routes_start_button_icon);
                yourButton.setCompoundDrawablesWithIntrinsicBounds(checkImg, null, null, null);
                yourButton.setBackgroundColor(green);
                yourButton.setText(custom_route_start);
            }
            return false;
        }
    });
Akbari Dipali
  • 2,173
  • 1
  • 20
  • 26
  • So which solution is better in ways of programming. Changing drawable, color and text in code (like your solution), or two buttons where only 1 is visible at a time? – Mark Molina Mar 19 '13 at 10:06
  • I have implemented one i have writen with programming but as you have wrote, you can also take 2 buttons and use same listener for the both – Akbari Dipali Mar 19 '13 at 10:11
0

Do you mean you want to change the button background color if you click the button? yes you can do it

first define the state

private int btnState = 1;
private final static int BUTTON_STATE_SELECTED = 0;
private final static int BUTTON_STATE_UNSELECTED = 1;

then set id to your button

android:id="@+id/btnRoute"
android:background="@color/green"
android:drawableLeft="@drawable/custom_routes_start_button_icon"
android:text="@string/custom_route_start"

declare the button in your activity

Button btnRoute = (Button) findviewbyid(R.id.btnRoute);

after that create an onclick listener that'll change the button color based on the state

private View.OnClickListener mOnClickBtnRoute = new View.OnClickListener() {
switch(btnState) {
case BUTTON_STATE_SELECTED:
btnRoute.setBackgroundColor(green);
btnRoute.setText(start);
Drawable img = getContext().getResources().getDrawable( R.drawable.custom_routes_start_button_icon );
btnRoute.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null );
btnState = BUTTON_STATE_UNSELECTED;
break;
case BUTTON_STATE_UNSELECTED:
btnRoute.setBackgroundColor(red);
btnRoute.setText(stop);
Drawable img = getContext().getResources().getDrawable( R.drawable.custom_routes_stop_button_icon );
btnRoute.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null );
btnState = BUTTON_STATE_SELECTED;
break;
}
};

then don't forget to set the listener to the button

btnRoute.setOnClickListener(mOnClickBtnRoute);

please remember all the code is coded here so maybe there'll be a mistype so please don't just copy paste but try to understand the concept :) and if you have some question about my answer feel free to ask in the comment!

Niko Adrianus Yuwono
  • 11,012
  • 8
  • 42
  • 64