serv-inc
serv-inc

Reputation: 38177

Change button background color as if pressed, but without the user pressing it

On Android, a Button changes its background color when pressed.

How can we tell a button that it is pressed (without firing the onClick-action), so that it changes color, without the user pressing it? (for example triggered by a swipe action)

It should change color briefly, and then change back.

There a quite a few questions concerning keeping the pressed state. This question asks, how to set the button_pressed state briefly, as if clicked, but without a real click.

Button.setPressed(true) has not given a color change, neither has Button.performClick().

Upvotes: 0

Views: 2656

Answers (4)

serv-inc
serv-inc

Reputation: 38177

To change a button state without anything else is done via

btn1.getBackground().setState(new int[]{android.R.attr.state_pressed});

To reset to ordinary, you use

btn1.getBackground().setState(new int[]{android.R.attr.state_enabled});

A Button's states can be found out via

btn1.getBackground().getState();

which resturns an int[]. You can compare its values to android.R.attr to find out which states are set.

Example Code

private void simulateClick(final ImageButton button,
                           final long clickDuration) {
    button.getBackground().setState(new int[]{android.R.attr.state_pressed});
    new Thread(new Runnable() {
        public void run() {
            try {
                Thread.sleep(clickDuration);
            } catch ( InterruptedException e ) {
                // not bad if interrupted: sleeps a bit faster (can happen?)
            }
            Count.this.runOnUiThread(new Runnable() {
                    public void run() {
                        button.getBackground().setState(new int[]{android.R.attr.state_enabled});
                    }
                });
        }}).start();
}

Explanation

Each View has a Drawable as background image. A Drawable can be of different subtypes, here it is a StateListDrawable, as defined per XML. (See @Lynx's answer as an example of a XML defined drawable).

This Drawable can be told which state it is to assume (via setState) and does the layout itself.

Upvotes: 4

Sheychan
Sheychan

Reputation: 2436

AsyncTask for button color change illusion:

private class ChangeButtonColorMomentarily extends AsyncTask<String, Void, String> {

    @Override
    protected void onPreExecute() {
        btn1.setBackgroundDrawable(new ColorDrawable(Color.rgb(50, 50, 50)));//pressed state
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {

        }
        return "";
    }

    @Override
    protected void onPostExecute(String result) {
        btn1.setBackgroundDrawable(new ColorDrawable(Color.rgb(200, 200, 200)));//normal state
    }

}

Also take note that if your API 16 above use setBackground() instead.

Upvotes: 2

Lynx
Lynx

Reputation: 131

First, create the effect when button is hovered, clicked etc in XML. Put this style in your drawable.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Pressed button -->
    <item android:drawable="@color/dark_green"
        android:state_focused="true"
        android:state_pressed="false"
        />
    <item android:drawable="@color/dark_green"
        android:state_focused="true"
        android:state_pressed="true"
        />
    <item android:drawable="@color/dark_green"
        android:state_focused="false"
        android:state_pressed="true"/>

    <!-- Normal button -->
    <item android:drawable="@color/green"
        android:state_focused="false"
        android:state_pressed="false"/>
</selector>

Then in your XML, initiates the style by using:

<Button
 android:layout_width="wrap_content"
 android:layout_height="match_parent"
 android:background="@drawable/the_style_in_drawable"
 android:text="click"/>

By putting the style in your XML, you don't have to initiate the style when button on click. Android will detect the button state and do the work for you. Just remember to put the state in selector.

Upvotes: 3

Anshul Tyagi
Anshul Tyagi

Reputation: 2196

For changing the color of button at that time, you can use setOnTouchListener as:

button.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                //Button Pressed
            }
            if(event.getAction() == MotionEvent.ACTION_UP){
                 //finger was lifted
            }
            return false;
        }
    });

Upvotes: 1

Related Questions