android - 纵向的 Viewpager 和横向的两个窗格
问题描述
我正在尝试实现一种布局,当设备以纵向显示时显示视图寻呼机,并在设备以横向显示时显示两个窗格。
所以我做了两个不同的布局文件,一个只有一个ViewPager,另一个有一个LinearLayout,另一个有两个FrameLayout,我觉得这里没有必要展示。这两种配置还有一个布尔值hasTwoPanes
。
@Inject FragmentOne fragmentOne;
@Inject FragmentTwo fragmentTwo;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
boolean hasTwoPanes = getResources().getBoolean(R.bool.hasTwoPanes);
TabLayout tabLayout = findViewById(R.id.tab_layout);
ViewPager viewPager = findViewById(R.id.view_pager);
if (hasTwoPanes) {
tabLayout.setVisibility(View.GONE);
} else {
tabLayout.setVisibility(View.VISIBLE);
tabLayout.setupWithViewPager(viewPager);
viewPager.setAdapter(new MyPagerAdapter(fm));
}
FragmentOne frag1 = (FragmentOne) fm.findFragmentByTag(getFragmentName(0));
if (frag1 != null) fragmentOne = frag1;
FragmentTwo frag2 = (FragmentTwo) fm.findFragmentByTag(getFragmentName(1));
if (frag2 != null) fragmentTwo = frag2;
if (hasTwoPanes) {
if (frag1 != null) {
fm.beginTransaction().remove(fragmentOne).commit();
fm.beginTransaction().remove(fragmentTwo).commit();
fm.executePendingTransactions();
}
fm.beginTransaction().add(R.id.frame_frag1, fragmentOne, getFragmentName(0)).commit();
fm.beginTransaction().add(R.id.frame_frag2, fragmentTwo, getFragmentName(1)).commit();
}
}
private class MyPagerAdapter extends FragmentPagerAdapter {
MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
return fragmentOne;
} else {
return fragmentTwo;
}
}
@Override
public int getCount() {
return 2;
}
}
private static String getFragmentName(int pos) {
return "android:switcher:" + R.id.view_pager + ":" + pos;
}
用 Dagger 注入了两个片段。如果不存在任何片段,则这些注入的片段将根据方向添加到视图分页器或布局中。
因为视图寻呼机适配器为其片段提供了名称,所以我需要知道该名称(因此是getFragmentName(int pos)
方法)才能在旋转后取回该片段。
结果是从纵向旋转到横向时状态正确恢复,但是从横向旋转纵向时,视图寻呼机完全为空。当我旋转回横向时,片段会重新出现。选项卡布局也有问题,没有滑动动画,我只能从一个选项卡连续滑动到另一个选项卡,在任何地方停止。
为了澄清事情,这发生在一个活动中,没有父片段。即使没有显示片段,onViewCreated
也会调用片段。视图寻呼机似乎正确地恢复了instantiateItem
. 此外,在调试时,片段具有added
真和hidden
假。这使它看起来像是一个视图寻呼机渲染问题。
- 如何让视图寻呼机显示我的片段?
- 有没有更好的方法来实现我想要的行为?
解决方案
您是否尝试过使用 PagerAdapter 而不是 FragmentPagerAdapter?您将更好地控制片段的创建和处理。否则你不知道 FragmentPagerAdapter 在做什么(他是为你做的,但可能是错的)。
您可以将大部分逻辑移动到该类中,使活动更清洁,并且可能还解决了您遇到的问题。
编辑:由于我们在这里讨论方向更改,您可能应该合并onConfigurationChanged
回调以更好地处理该逻辑。
推荐阅读
- android - 与经典蓝牙配对后,我可以在不使用 GATT 连接的情况下向 ble 4.2 或 ble 5 模块发送数据吗
- php - 加载视图后如何执行函数
- javascript - 在使用 JS/Jquery 从 .txt 文件呈现内容时在单词之间添加空格
- c# - 当文件编码为 Unicode 时,C# XmlDocument.Load(string) 失败
- json - 使用 jq,获取数组中 shell 定义的 JSON 对象内的特定键的值
- c# - 如何使用 mscorlib.dll 而不是 mscorlib.ni.dll?
- javascript - 超过 1 页的 pdf 文件未在 iframe 中显示
- ionic-framework - Ionic 3 - 不推荐使用 getRootNav - 尝试在没有选项卡的情况下设置 root
- drupal - 在 Drupal 8 视图中,无法将段落字段添加到公开过滤器
- c++ - 有没有办法在使用 GLFW 按下一个键后只处理一个输入事件?