Android: click event after Activity.onPause()
Asked Answered
N

3

12

There are two buttons, button A starts another activity inside its onClickListener using simple Activity.startActivity() method, button B does some other work inside its onClickListener.

When I click button B and immediately after button A, then new activity is started, onPause() lifecycle event for old activity is fired, but also onClick event for second button is fired, but after Activity.onPause() which leads to some state inconsistencies in my app.

Is there any way to prevent touch/click events from being delivered after onPause() without using isPaused flag?

**Edit:**My code:

public class MainActivity extends AppCompatActivity {

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

        Button buttonA = (Button) findViewById(R.id.activity_button);
        buttonA.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, TestActivity.class));
            }
        });

        Button buttonB = (Button) findViewById(R.id.log_button);
        buttonB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("TEST", "onClick");
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e("TEST", "onPause");
    }
}

Basically if you are fast enough and click button B right after button A then B's onClick is fired after onPause.

Navarino answered 14/7, 2016 at 7:46 Comment(6)
Could you post some code of what you are trying to do to make it clearer to anyone trying to help?Peugia
I just don't want click events to be delivered after onPause() is fired.Navarino
there is no way that onClick event fires automatically. If you put your code then we can understand better to find out our problemEarn
@Earn it doesn't happen automatically, I wrote that I click both buttonsNavarino
@VigneshKarthikeyan I added the code which reproduces the problem.Navarino
I understand your problem now. You said your view hierarchy is complex. I have one trick in mind. you can use a frame layout as parent & add a full screen size view with click enabled = false. when clickA begins you show that view. By doing that your clickB will be prevented.Earn
N
2

This whole concept can be easily solved using ViewModels + lifecycle-aware LiveDatas where LiveData expose events to UI-layer only when it's allowed.

Navarino answered 2/9, 2019 at 7:12 Comment(1)
Can you give more details on this? Thanks!Certificate
H
3

In OnClickListener of button A, disable the button b.

Button.setEnabled(false);

Just enable the button at the of A's onClickListener or at onResume depending on your requirements.

Himelman answered 14/7, 2016 at 8:5 Comment(2)
Thanks for this answer, however if my view hierarchy is really complex I would have to disable many views.Navarino
@Navarino override Activity#dispatchTouchEvent(MotionEvent ev) thenWinfrid
A
2

I know this question is very old and far far away from being active. I came across this question via a blog.

A simple solution which I can think off is maintaining a flag globally in Activity A and setting it immediately inside onClick of Button A. This flag can be reset in onResume of Activity A.

This flag should be used at the top of onClick handler and all the clicks of all the views must be ignored. Of course, this requires that there is a single onClick method.

private boolean isOnClickIgnored= false;

@Override
public void onResume() {
    super.onResume();
    isOnClickIgnored = false;
}

@Override
public void onClick(View v) {
    super.onClick(v);
    if(isOnClickIgnored){
        return;
    }
    switch (v.getId()){
        case R.id.btnA:
            isOnClickIgnored = true;
            // Do button a things like opening Activity B
            break;
        case R.id.btnB:
            // Do button b things
            break;
        case R.id.btnZ:
            // Do button z things
            break;
    }
}
Anaxagoras answered 21/8, 2019 at 18:5 Comment(0)
N
2

This whole concept can be easily solved using ViewModels + lifecycle-aware LiveDatas where LiveData expose events to UI-layer only when it's allowed.

Navarino answered 2/9, 2019 at 7:12 Comment(1)
Can you give more details on this? Thanks!Certificate

© 2022 - 2024 — McMap. All rights reserved.