解决方案:
我发现解决这个问题的最佳方法是通过 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添加到DONE和CANCEL 按钮。在这里,我使用我之前对父 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
}
我们在没有重新创建操作栏的情况下完成了这一切。这是它的外观!
感谢阅读,祝您编码愉快!