【问题标题】:HOW TO Revert Action Bar after Switching Fragments如何在切换片段后恢复操作栏
【发布时间】:2016-02-11 08:00:19
【问题描述】:

问题:

Fragment 回栈是为了在一个活动中向后遍历一堆片段时不会将操作栏恢复到前一个片段中的原始状态。

为什么会这样?

原来,Action Bar 实际上是附加到 Activity 本身,而不是片段!请记住,片段只是 UI 的模块化位,必须明确指定对其他片段、活动部分甚至操作栏的控制。

继续阅读解决方案...

【问题讨论】:

    标签: android android-fragments android-actionbar


    【解决方案1】:

    解决方案:

    我发现解决这个问题的最佳方法是通过 Reto Meier 的 answer 对上一个问题的一般描述来完成。我的解决方案只会更深入地扩展他的答案。

    我们想要建立的是,我们不希望每次切换到不同的片段时都重新创建操作栏,因为它不是很有效。我将引导您完成我为学生安排应用程序编写的。它不是很复杂,它的入职体验是由一个活动中的多个片段组成的。

    要完成这项工作,我们需要确保使用 replace() 在片段之间切换。这比将片段层叠在一起要好,因为它允许您为每个片段单独配置操作栏。

    第一段代码来自 Activity 的内部类 LoginOptionsFragment,在其 onCreateView() 方法中。

    @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_login_options, container, false);
            //LoginOptionsFragment will have its own action bar
            setHasOptionsMenu(true);
            //inject views. e.g: Button add_course
            ButterKnife.inject(this, rootView);
    
            add_course.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    getFragmentManager().beginTransaction()
                            //exchange fragments. no messy clean-up necessary.
                            .replace(R.id.container, new AddCourseFragment())
                            .addToBackStack(null)
                            .commit();
                }
            });
    
            return rootView;
        }
    

    在这里,我不仅要确保通过 setHasOptionsMenu(true) 致电 onCreateOptionsMenu(),而且主要是只要点击“添加课程”按钮即可切换到 AddCourseFragment,新的 Fragment 将替换旧的 Fragment 作为 Activity 的主要子项。接下来,在我们覆盖onCreateOptionsMenu() 之后,我们来到onResume(),但我们稍后会谈到;)

    其次,我们到达AddCourseFragment,我们甚至为操作栏添加了一个自定义完成-取消视图。那么我们来看看代码吧!

    @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            // BEGIN_INCLUDE (inflate_set_custom_view)
            // Inflate a "Done/Cancel" custom action bar view.
            final ActionBar actionBar = getActivity().getActionBar();
            inflater = (LayoutInflater) actionBar.getThemedContext()
                    .getSystemService(LAYOUT_INFLATER_SERVICE);
    
            //inflate custom action bar view
            View customActionBarView = inflater.inflate(
                    R.layout.actionbar_custom_view_done_cancel, null);
    
            //set listeners to items in the view
            customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                        // "Done"
                            //remove custom view from action bar
                            actionBar.setDisplayShowCustomEnabled(false);
                            getFragmentManager().popBackStack();
                            //add course to list
                        }
                    });
            customActionBarView.findViewById(R.id.actionbar_cancel).setOnClickListener(
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                        // "Cancel"
                            //remove custom view from action bar
                            actionBar.setDisplayShowCustomEnabled(false);
                            getFragmentManager().popBackStack();
                        }
                    });
    
            // Show the custom action bar view and hide the normal Home icon and title.
            actionBar.setDisplayOptions(
                    ActionBar.DISPLAY_SHOW_CUSTOM,
                    ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME
                            | ActionBar.DISPLAY_SHOW_TITLE);
            actionBar.setCustomView(customActionBarView,
                    new ActionBar.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT));
            actionBar.setDisplayHomeAsUpEnabled(false);
            // END_INCLUDE (inflate_set_custom_view)
    
            View rootView = inflater.inflate(R.layout.fragment_add_course, container, false);
            ButterKnife.inject(this, rootView);
    
            return rootView;
        }
    

    您需要注意的ONLY部分是OnClickListener添加到DONECANCEL 按钮。在这里,我使用我之前对父 Activity 的操作栏的引用并告诉它停止显示自定义视图。现在除了这个特定的方法之外,还有更多的setDisplayXEnabled() 方法可以传入false。之后,我会弹出 backstack 以到达上一个片段。

    但我如何真正恢复操作栏!?

    方法如下。还记得我们LoginOptionsFragment 中的onResume() 方法吗?好吧,一旦片段从后台堆栈重新成为焦点,就会调用onResume()!因此,如果我们覆盖它并重新启用我们想要的操作栏部分,我们就赢了,对吧?是的,我们这样做。这是您需要添加到onResume() 的所有内容。

    @Override
        public void onResume() {
            super.onResume();
            ActionBar actionBar = getActivity().getActionBar();
            actionBar.setDisplayShowHomeEnabled(true); //show Home icon
            actionBar.setDisplayShowTitleEnabled(true); //show title
    //      actionBar.setDisplayUseLogoEnabled(true); <--- more options
    //      actionBar.setDisplayHomeAsUpEnabled(true); <--- more options
        }
    

    我们在没有重新创建操作栏的情况下完成了这一切。这是它的外观!

    感谢阅读,祝您编码愉快!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多