【问题标题】:Android Studio - Navigation drawer with back stackAndroid Studio - 带回栈的导航抽屉
【发布时间】:2020-12-11 14:06:00
【问题描述】:

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

如何使用后台堆栈?

@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);

      ...
    }

【问题讨论】:

    标签: android navigation drawer


    【解决方案1】:

    我解决了这个问题。

    我创造了自己的历史:

    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);
                } else
                    navigationView.getMenu().performIdentifierAction(R.id.nav_home, 0);
            } else {
                navigationView.getMenu().performIdentifierAction(R.id.nav_home, 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() {
        }
    

    最后我在 Fragments 中使用了它们,带有 OnBackPressed 事件和 onTouch 监听器(因为我也使用 swipe 来返回堆栈)

    这是片段中的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();
                }
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-03
      • 2015-07-21
      • 2020-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多