Android Studio-带后置堆栈的导航抽屉

问题描述

我有一个导航抽屉活动,我想使用后退按钮:当我用导航抽屉打开一个新片段时,如果用户按下后退按钮,我想回到上一个片段。

如何使用后置堆栈?

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        initDataTags();
        requestwindowFeature(Window.FEATURE_NO_TITLE);
        getwindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        ...

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        toolbar.setTitleTextColor(getColor(R.color.white));
        setSupportActionBar(toolbar);
        drawer = findViewById(R.id.drawer_layout);
        navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home,R.id.nav_favourites,R.id.nav_profile,R.id.nav_login,R.id.nav_register,R.id.nav_cheats,R.id.nav_puskak,R.id.nav_settings,R.id.nav_categories,R.id.nav_act_category_item,R.id.nav_act_item,R.id.nav_library,R.id.nav_video,R.id.web_fragment,R.id.nav_gdpr,R.id.nav_selected_puska_fragment
        )
                .setopenableLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this,R.id.nav_host_fragment);

        NavigationUI.setupActionBarWithNavController(this,navController,mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView,navController);

      ...
    }

解决方法

我解决了这个问题。

我创造了自己的历史

import java.util.ArrayList;

public class HistoryData {
    static ArrayList<String> history = new ArrayList<>();
    static ArrayList<String> historyForward = new ArrayList<>();
    private static final String TAG = "HistoryData";
    public static String lastItem = "";
    public static int actItem = 0;

    public static void add(String item){
        if(history.size() == 0)
            history.add(item);
        if (!item.equals(history.get(history.size() - 1)) && !lastItem.equals(item)) {
            history.add(item);
        }
        actItem = history.size() - 1;
        Log.d(TAG,"add: " + item);
        for (int i = 0; i < history.size(); i++){
            Log.d(TAG,"get: index(" + i + ") = " + history.get(i));
        }
    }

    public static int size(){
        return history.size();
    }

    public static String get(int index){
        Log.d(TAG,"get: " + history.get(index));
        Log.d(TAG,"get: at index: " + index);
        for (int i = 0; i < history.size(); i++){
            Log.d(TAG,"get: index(" + i + ") = " + history.get(i));
        }
        return history.get(index);
    }

    public static String getLast(){
        return history.get(history.size() - 1);
    }

    public static String getPrev(){
        return history.get(history.size() - 2);
    }

    public static String remove(int index){
        Log.d(TAG,"remove: " + history.get(index));
        Log.d(TAG,"remove: at index: " + index);
        historyForward.add(history.get(index));
        actItem = history.size() - 1;
        for (int i = 0; i < historyForward.size(); i++){
            Log.d(TAG,"remove: hFw(" + i + ") = " + historyForward.get(i));
        }
        return history.remove(index);
    }

    public static int undoSize(){
        return historyForward.size();
    }

    public static String undo(){
        String result = historyForward.get(historyForward.size() - 1);
        add(result);
        historyForward.remove(historyForward.size() - 1);
        for (int i = 0; i < historyForward.size(); i++){
            Log.d(TAG,"undo: hFw(" + i + ") = " + historyForward.get(i));
        }
        return result;
    }
}

我做了一个导航课

import android.util.Log;

import com.google.android.material.navigation.NavigationView;
import com.wecreatethefuture.puskapp.Activities.MainActivity;
import com.wecreatethefuture.puskapp.data.Constant;
import com.wecreatethefuture.puskapp.data.HistoryData;

public class Navigate {
    private static final String TAG = "Navigate";

    public static void back(){
        MainActivity mainActivity = new MainActivity();
        NavigationView navigationView = mainActivity.navPub();
        Log.d(TAG,"handleOnBackPressed: HD size: " + HistoryData.size());
        if (HistoryData.size() > 1){
            String prev = HistoryData.getPrev();
            Log.d(TAG,"handleOnBackPressed: prev: " + prev);
            HistoryData.remove(HistoryData.size() - 1);
            if(prev.equals(Constant.FRAGMENT_SETTING)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_settings,0);
            }
            else if(prev.equals(Constant.FRAGMENT_LIBRARY)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_library,0);
            }
            else if(prev.equals(Constant.FRAGMENT_GDPR)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_gdpr,0);
            }
            else if(prev.equals(Constant.FRAGMENT_FAVORITES)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_favourites,0);
            }
            else if(prev.equals(Constant.FRAGMENT_VIDEOS)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_video,0);
            }
            else if(prev.equals(Constant.FRAGMENT_CATEGORIES)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_categories,0);
            }
            else if(prev.equals(Constant.FRAGMENT_CHEATS)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_cheats,0);
            }
            else if(prev.equals(Constant.FRAGMENT_ACT_CATEGORY_ITEM)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_act_category_item,0);
            } else
                navigationView.getMenu().performIdentifierAction(R.id.nav_home,0);
        } else {
            navigationView.getMenu().performIdentifierAction(R.id.nav_home,0);
        }
    }

    public static void forward(){
        MainActivity mainActivity = new MainActivity();
        NavigationView navigationView = mainActivity.navPub();
        Log.d(TAG,"handleOnBackPressed: HD size: " + HistoryData.size());
        if (HistoryData.undoSize() > 0){
            String next = HistoryData.undo();
            HistoryData.add(next);
            if(next.equals(Constant.FRAGMENT_SETTING)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_settings,0);
            }
            else if(next.equals(Constant.FRAGMENT_LIBRARY)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_library,0);
            }
            else if(next.equals(Constant.FRAGMENT_GDPR)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_gdpr,0);
            }
            else if(next.equals(Constant.FRAGMENT_FAVORITES)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_favourites,0);
            }
            else if(next.equals(Constant.FRAGMENT_VIDEOS)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_video,0);
            }
            else if(next.equals(Constant.FRAGMENT_CATEGORIES)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_categories,0);
            }
            else if(next.equals(Constant.FRAGMENT_CHEATS)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_cheats,0);
            }
            else if(next.equals(Constant.FRAGMENT_ACT_CATEGORY_ITEM)){
                navigationView.getMenu().performIdentifierAction(R.id.nav_act_category_item,0);
        }
    }
}

经过Google搜索,我发现了一个OnSwipeTouchListener

import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class OnSwipeTouchListener implements View.OnTouchListener {
    private GestureDetector gestureDetector;
    Context c;

    public OnSwipeTouchListener(Context c) {
        gestureDetector = new GestureDetector(c,new GestureListener());
        this.c = c;
    }
    public boolean onTouch(final View view,final MotionEvent motionEvent) {
        return gestureDetector.onTouchEvent(motionEvent);
    }
    private final class GestureListener extends
            GestureDetector.SimpleOnGestureListener {
        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;
        @Override
        public boolean onDown(MotionEvent e) {
            return super.onDown(e);
        }
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            onClick();
            return super.onSingleTapUp(e);
        }
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            onDoubleClick();
            return super.onDoubleTap(e);
        }
        @Override
        public void onLongPress(MotionEvent e) {
            onLongClick();
            super.onLongPress(e);
        }


        @Override
        public boolean onFling(MotionEvent e1,MotionEvent e2,float velocityX,float velocityY) {
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight();
                        } else {
                            onSwipeLeft();
                        }
                    }
                }
            }
            catch (Exception exception) {
                exception.printStackTrace();
            }
            return false;
        }
    }
    public void onSwipeRight() {
        Navigate.back();
    }
    public void onSwipeLeft() {
        Navigate.forward();
    }
    private void onClick() {
    }
    private void onDoubleClick() {
    }
    private void onLongClick() {
    }

最后,我在带有OnBackPressed事件和onTouch侦听器的片段中使用了它们(因为我也使用了向后滑动滑动)

这是片段中的onCreate方法:

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        HistoryData.add(Constant.FRAGMENT_ACT_CATEGORY_ITEM);
        OnBackPressedCallback callback = new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                Navigate.back();
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this,callback);
    }

然后将OnSwieTouchListener附加到我的视图中,例如:

ConstraintLayout constraintLayout = root_view.findViewById(R.id.constraintLayoutCategoryItemContainer);
        constraintLayout.setOnTouchListener(new OnSwipeTouchListener(getActivity().getBaseContext()) {
            @Override
            public void onSwipeLeft() {
                super.onSwipeLeft();
            }
            @Override
            public void onSwipeRight() {
                super.onSwipeRight();
            }
        });

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...