我的应用程序在页面之间滚动时使用了 FragmentStatePagerAdapter 有一个小问题。
首先,我将描述如何使用精简版本构建应用程序。
应用说明
我有一个 Activity 将所有东西放在一起。这个 Activity 反过来托管一个 Fragment,在本例中称为 Pager。
这个 Pager 类内部有一个 ViewPager,其中一个 FragmentStatePagerAdapter 作为内部类,用于为 ViewPager 提供片段。提供给 ViewPager 的片段是 FragmentA 的实例。FragmentA 在 ActionBar 上有自己的内容和自己的项,但也可以依次打开其他 Fragment。在我的“真实”应用程序中,这可以通过单击 ListView 中的某个项目或单击 ActionBar 上的按钮来完成。在这个简化的例子中,FragmentA 可以通过一个按钮打开 FragmentB。
到目前为止,这一切正常。
问题
当从任何 FragmentA 片段打开 FragmentB 时,它会在 ActionBar 中正确显示其自己的内容和菜单,替换 FragmentA 的菜单。但是,当通过后退按钮导航返回时,FragmentA 的 ActionBar 永远不会恢复到 FragmentA-actionbar 在打开 FragmentB 之前的状态,而是空的。
可能奇怪的行为
当我更改 MainPagerAdapter 扩展 FragmentPagerAdapter 而不是 FragmentStatePagerAdapter 时,突然之间它工作得很好,我真的不明白为什么会这样。此外,当 Fragment 包含在 FragmentStatePagerAdapter 中时,手动调用 supportInvalidateOptionsMenu() 根本不起作用。
我查看了这两种适配器类型的来源,但我无法弄清楚为什么其中一种有效而另一种无效。
MainActivity.java
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager()
.beginTransaction()
.addToBackStack("Start")
.replace(R.id.container, new Pager())
.commit();
}
public void openB() {
getSupportFragmentManager()
.beginTransaction()
.addToBackStack("Start1")
.replace(R.id.container, new FragmentB())
.commit();
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/container">
</RelativeLayout>
寻呼机.java
public class Pager extends Fragment {
ViewPager mViewPager;
MainPagerAdapter mainPagerAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.wrapper_layout, null);
mViewPager = (ViewPager)v.findViewById(R.id.viewpager);
mainPagerAdapter = new MainPagerAdapter(getChildFragmentManager());
mViewPager.setAdapter(mainPagerAdapter);
return v;
}
private class MainPagerAdapter extends FragmentStatePagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return new FragmentA();
}
@Override
public int getCount() {
return 2;
}
}
}
wrapper_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
片段A.java
public class FragmentA extends Fragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
menu.add("A-Menu");
}
@Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.a, null);
Button b = (Button)v.findViewById(R.id.button2);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().supportInvalidateOptionsMenu();
}
});
Button b2 = (Button)v.findViewById(R.id.button);
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((MainActivity)getActivity()).openB();
}
});
return v;
}
}
一个.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:id="@+id/button"
android:layout_gravity="center_horizontal"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invalidate"
android:id="@+id/button2"
android:layout_gravity="right"
/>
</LinearLayout>
片段B.java
public class FragmentB extends Fragment{
@Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
menu.add("B-Menu");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.b, null);
return v;
}
}