Android. How do I keep a button displayed as PRESSED until the action created by that button is finished?
Asked Answered
S

7

6

I have button_focused, button_pressed, and button_normal images. When I press the button, the button_pressed image is displayed and the action related to the button pressing begins.

When I quit pressing the button, the action continues but the button returns to button_normal image being displayed.

How can I set the button image being displayed to button_pressed during the entire action then reset to the button_normal image?

Thank you for your time

Silda answered 12/1, 2011 at 22:51 Comment(2)
Why would android know what the button press does? You'll have to manage the states yourself.Fog
I think he means that Falmarri .. he already hints that he has states at the start of his question. What he wanted to know is how to link those states in with actions. So let's say he has buttonA which when pressed loads a photo - when he presses buttonA is shows active on the press down but when the finger comes off it reverts back to the normal state (the way he has currently set up) however the photos is still loading and it would look weird. So he wonders if he can link state to the loading action some how. Note: if user527405 is female please change all male terms to female above :)Turgor
C
4

I used a function like

void setHighlighted(boolean highlight) {
    button.setBackgroundResource( highlight
                                ? R.drawable.bbg_pressed
                                : R.drawable.button_background);
}

where button_background is a selector defined in button_backgroung.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_pressed="true" android:drawable="@drawable/bbg_pressed"></item>
    <item android:state_focused="true" android:drawable="@drawable/bbg_selected"></item>
    <item android:drawable="@drawable/bbg_normal"></item>
</selector>

That is, this code does not interfere with the pressed state used by the Android framework; instead, it changes the background so that the button looks pressed.

Calais answered 7/10, 2013 at 12:31 Comment(0)
G
3

To make it a bit clearer if you are just in need of a two state button:

You do not need your own button.xml. You can work with the normal of Android.

The button.setPressed(true) will not work if you are clicking the button, because Android will reset it once you let go of the button. Try to set another buttons setPressed state first to see the effect.

Which means, to use it on the same button it must be set delayed. Here is a working example. Of course, the mentioned approach (by long id 18..) on changing the background works too.

   private final Handler mHandler = new Handler();
   rootView.findViewById(R.id.yourButton).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            boolean pressed = false;
            if (v.getTag() instanceof Boolean)
                pressed = (boolean) v.getTag();
            final boolean newPressed = !pressed;
            // setTag to store state
            v.setTag(newPressed);
            final View vRun = v;
            Runnable run = new Runnable() {
                @Override
                public void run() {
                    vRun.setPressed(newPressed);
                }
            };
            mHandler.post(run);
            // mHandler.postDelayed(run, 5);
        }
    });
Galleass answered 1/3, 2015 at 0:47 Comment(1)
This should be accepted as the answer. The key is "to use it on the same button it must be set delayed". Unfortunately the question then becomes, what delay to use? 5ms did not work when I clicked fast. 50ms was much better, but sometimes it still wouldn't work if I clicked very fast. So I settled on 100ms. This does, however, feel like a hack.Lithophyte
A
1

If you change the image in the button manually in its onClick method, then when an action finishes it can set the normal image for that button back. If the action is very quick then change will not show properly - it may need a delay code as well.

Amenable answered 12/1, 2011 at 23:17 Comment(1)
I think this is possibly the best answer here but an example is needed!Turgor
S
1

I used

NAME_OF_BUTTON.setImageResource(0xvalueofbutton_pressed image listed in R.java);

then when the action terminates I copied the code and inserted the integer value of button_normal.

I did this differently before and I cannot find my backups or hard copies of my code.

Thank you again for your responses.

Silda answered 12/1, 2011 at 23:29 Comment(1)
Just a side note to make your life easier. You should not use the values from R.java but instead refer the variables directly. THe values can change when IDs are recreated. So instead just write: NAME_OF_BUTTON.setImageResource(R.button_pressed);Gaylagayle
I
1

Use (buttonName).setPressed(true)

And make sure you have kept the appropriate xml file for the drawable that defines which drawable to use for states like pressed,focused etc:

Indiscriminate answered 11/4, 2011 at 9:37 Comment(0)
H
1

Just adding my 2 cents as another alternative. Instead of button.setPressed, which will lose the state from the selector once the user let go of the button, you can use setSelected(true). Just make sure to go back with setSelected(false) when you finish the action.

        btn.setOnClickListener( view ->  {
        view.setSelected(true);
    });

And add the drawable selector as background for the button:

<item android:drawable="@drawable/btn_selected" android:state_selected="true"></item>
Hysell answered 5/3, 2018 at 21:33 Comment(0)
R
1

Old question but here's what I did that seems simpler than all of the above. In the button's onclick:

thisButton
    .getBackground()
    .setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.MULTIPLY);

My buttons are using a drawable resource (not sure if that matters) and when the user clicks one I set the color filter I want which is the same color I use for the "pressed" state so it looks like it stays pressed.

To clear it use:

thisButton.getBackground().clearColorFilter();
Rina answered 24/6, 2020 at 22:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.