0

I am working on a project where a button should stay pressed when the user touches or taps on it. I have done it successfully using:

button.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        button.setPressed(true);
        return true;
    }
});

Now, my problem is: when I pull down the status bar or minimize the app using home/back button (from navigation bar), the button becomes unpressed.

I have tried to solve this using:

onSaveInstanceState(Bundle savedInstanceState)

to save the pressed state of the button, but it didn't work.

Now, how can I solve this problem?

Rawnak Yazdani
  • 1,333
  • 2
  • 12
  • 23
  • Does this answer your question? [How to save an activity state using save instance state?](https://stackoverflow.com/questions/151777/how-to-save-an-activity-state-using-save-instance-state) – Jake Lee Jul 24 '20 at 16:57
  • It doesn't solve my problem, because I have tried using onSaveInstanceState, but it didn't work. onSaveInstanceState only works when I rotate the screen, but it doesn't work when I pull down the status bar or minimize the app. – Rawnak Yazdani Jul 24 '20 at 17:09
  • You probably want `onPause` and `onResume`. – Jake Lee Jul 24 '20 at 17:59
  • How do **onPause** and **onResume** work? I have no idea. Would you provide me with specific code? @JakeLee – Rawnak Yazdani Jul 24 '20 at 19:39
  • Hey you should only need onResume. So store the button state in an instance field boolean. Then override onResume as follows: @Override onResume(){super.onResume(); if(buttonPressed){button.setPressed(true);}} – River_B Jul 24 '20 at 20:07
  • **onPause** and **onResume** only works when I minimize the app. But when I pull down the status bar, it doesn't work. – Rawnak Yazdani Jul 25 '20 at 10:09

1 Answers1

0

I have found two solutions to this (I personally like the second one).

Solution 1

Firstly, I have used onResume() and a flag variable to save the button's state when user minimizes the app.

Secondly, I have used onWindowFocusChanged() and that same flag variable to save the button's state when user pulls down the status bar.

Demo code:

public class MainActivity extends AppCompatActivity {

    Button button;

    int flag=0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.button);

        button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                button.setPressed(true);
                flag=1;

                return true;
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();

        if(flag==1){
            button.setPressed(true);
        }else{
            button.setPressed(false);
        }

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        // handle when the user pull down the notification bar where
        // (hasFocus will ='false') & if the user pushed the
        // notification bar back to the top, then (hasFocus will ='true')

        super.onWindowFocusChanged(hasFocus);

        if (!hasFocus) {
            Log.i("Tag", "Notification bar is pulled down");

        }
        else {
            Log.i("Tag", "Notification bar is pushed up");
            if(flag==1){
                button.setPressed(true);
            }else{
                button.setPressed(false);
            }
        }

    }
}

Solution 2:

Firstly, I have created a file in drawable named button_bg.xml:

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

    <item android:state_selected="false" android:state_focused="false"
        android:state_pressed="false"
        android:drawable="@drawable/button_disabled">
    </item>


    <item android:state_selected="true"
        android:drawable="@drawable/button_default">
    </item>


    <item android:state_focused="true"
        android:drawable="@drawable/button_default">
    </item>


    <item android:state_pressed="true"
        android:drawable="@drawable/button_default">
    </item>

</selector>

Create two files in drawable (button_disabled.xml & button_default.xml) which are used in button_bg.xml.

button_disabled.xml:

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

    <solid android:color="#b6b7b5" />

    <padding
        android:bottom="7dp"
        android:left="7dp"
        android:right="7dp"
        android:top="7dp" />

    <stroke
        android:width="2dp"
        android:color="#050303" />

    <corners android:radius="15dp" />

</shape>

button_default.xml:

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

    <solid
        android:color="#6FA803"/>


    <padding
        android:bottom="7dp"
        android:left="7dp"
        android:right="7dp"
        android:top="7dp" />

    <stroke
        android:width="2dp"
        android:color="#050303" />

    <corners android:radius="15dp" />

</shape>

Then, I have added this button_bg.xml file as a background of my button:

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/button_bg"
    android:text="Button" />

Lastly, I have used setOnClickListener() and View.setSelected() to select the button view and stay pressed:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        v.setSelected(true);

    }
});

The reason I like the second solution is: I don't need to handle the button's state manually. So, when I will be working on with several buttons, the second solution will be more handy.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Rawnak Yazdani
  • 1,333
  • 2
  • 12
  • 23