Android Activity page jumps (the Activity that is backed to does not exist in the page stack)

Table of contents

1. Problem: the page jumps, and the Activity that is back to does not exist in the page stack

Two, the solution

1. Rewrite the back click event

2. Enter and exit animation

2.1 Set the back animation

2.2 Set forward animation

3. Solve the problem of page duplication

(1) Set the page to singleTask mode

(2) The page jumps backwards and destroys the current page

4. The effect of clicking the back button on the page is consistent with that of clicking the back button


1. Problem: the page jumps, and the Activity that is back to does not exist in the page stack

Encountered in previous projects, a business has more than a dozen pages, but the entry point may not be the first page, but any subsequent page. At this time, there are no middle pages in the page stack. But when you press the back button, you need to be able to return to the previous page. At this time, you can actually only open a new page. At this time, the backward animation is also the entrance animation, which will feel strange. At this time, we need to judge whether to move forward or backward when opening a new page, and set the corresponding custom entry and exit animations.

Logical example, there are 5 pages (1->5) in total, directly enter page 3, then press "Next" on the page to jump to page 4, press the back button or the back button on the page to return to page 2 . There is no problem in opening a new page in the next step, but if you want to go back, there is only page 3 in the page stack at this time, so you need to open a new page. If you use the default effect, it will be logically backward, but actually it is an entrance animation.

Two, the solution

1. Rewrite the back click event

When the back button is clicked in the Activity,  the onBackPressed()  method will be called, and this method needs to be rewritten.

(1) First, rewrite  onBackPressed()  and change it to the content to be processed when the back button is clicked, that is: open the new page to be returned to;

(2) Then, call  the finish()  method to destroy the current page.

Sample code (on the third page, click the back button to jump to the second page)

    @Override
    public void onBackPressed() {
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
        finish();
    }

2. Enter and exit animation

You can use  the overridePendingTransition(int enterAnim, int exitAnim)  method

overridePendingTransition(int enterAnim, int exitAnim);

This method needs to be called after startActivity() or finish() to take effect.

2.1 Set the back animation

To set the backward animation, use  the overridePendingTransition(int enterAnim, int exitAnim)  method. Because all backs use the same back animation, you can put this method in onBackPressed() of the parent class .

Sample code in BaseActivity

    @Override
    public void onBackPressed() {
        // 设置动画(进场动画, 出场动画)
        overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
        super.onBackPressed();
    }

The entry and exit animation is placed  in res->anim 

enter_from_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromXDelta="-100%p"
        android:toXDelta="0%p" />
</set>

exit_to_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromXDelta="0%p"
        android:toXDelta="100%p" />
</set>

2.2 Set forward animation

It is best to match the forward animation of the page with the backward animation, and also call  the overridePendingTransition(int enterAnim, int exitAnim)  method.

sample code

        btn_next_step.setOnClickListener(v -> {
            Intent intent = new Intent(this, ThirdActivity.class);
            startActivity(intent);
            overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
        });

The entry and exit animation is placed  in res->anim 

enter_from_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromXDelta="100%p"
        android:toXDelta="0%p" />
</set>

exit_to_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromXDelta="0%p"
        android:toXDelta="-100%p" />
</set>

3. Solve the problem of page duplication

There are a total of three pages in the demo, and the logical order is 1->2->3. When you actually open the APP, you will directly enter page 3. This means that there is only page 3 in the page stack, and a new page 2 will be opened when the page is turned back, and a new page 1 will be opened when the page 2 is moved back. The implementation method is the above two steps. But there will be a problem. When page 1 and page 2 already exist in the page stack, opening a new page in the back will cause multiple instances of the same page to appear in the page stack. For example, pages 1, 2, and 3 are all in the page stack. This is to click the back button on page 3 to open a new page 2, and then page 3 is destroyed. This means that there are two pages 2 in the page stack.

There are two solutions

(1) Set the page to singleTask mode

The Activity can be set to singleTask mode, so that each Activity will only have one instance in the current page stack. The setting method is: in the AndroidManifest file, set the launchMode attribute of the Activity to singleTask.

When opening an Activity, if there is no instance of this Activity in the page stack, create a new Activity instance and put it on the stack; if there is already an instance of this Activity in the page stack, pop all the Activities on this instance out of the stack, Make this instance at the top of the page stack, and this Activity can interact with the user.

code example

        <activity
            android:name=".SecondActivity"
            android:launchMode="singleTask" />

(2) The page jumps backwards and destroys the current page

The second method is to call the finish() method to destroy the original page after opening the new page when the page jumps backwards .

In this way, there is actually only one page in the page stack, which is the page currently displayed to the user, so there will be no problem of page duplication.

However, every time you jump backward, you have to call the finish() method, which feels a bit troublesome, but the advantage is that it saves memory.

sample code

        btn_next_step.setOnClickListener(v -> {
            Intent intent = new Intent(this, ThirdActivity.class);
            startActivity(intent);
            overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
            finish();
        });

4. The effect of clicking the back button on the page is consistent with that of clicking the back button

When the back button on the page is clicked, the onBackPressed()  method should also be called  to keep the effect of clicking the back button consistent.

However, the back button in the general page is in the custom Title, and the custom Title is generally abstracted into an independent control. At this time, you need to call the onBackPressed()  method in the listening event of the back button in the custom Title  . Of course, at this time, it is necessary to check that the context of the control is an Activity, and it can be called only after it is transformed into an Activity.

Made a Demo, specifically to realize the function of the back button, the sample code is as follows:

package com.song.activitystartdemo;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

public class BackButton extends LinearLayout {
    Context context;

    public BackButton(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public BackButton(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public BackButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }

    public BackButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.context = context;
        init();
    }

    private void init() {
        View view = LayoutInflater.from(context).inflate(R.layout.btn_back, this);
        Button button = view.findViewById(R.id.button);
        button.setOnClickListener(v -> {
            if (context instanceof Activity) {
                ((Activity) context).onBackPressed();
            }
        });
    }

}

Guess you like

Origin blog.csdn.net/sgx1825192/article/details/116139262
Recommended