在画象和两个窗格的Viewpager在风景

Nic*_*las 9 android android-configchanges android-fragments 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;
}
Run Code Online (Sandbox Code Playgroud)

用Dagger注射两个碎片.如果尚未存在碎片,则根据方向将这些注入的碎片添加到视图寻呼机或布局中.

因为视图寻呼机适配器为其片段命名,所以我需要知道该名称(因此getFragmentName(int pos)方法)在旋转后返回该片段.

结果是当从纵向旋转到横向时状态被正确恢复,但是当从横向旋转纵向时,视图寻呼机完全是空的.当我旋转回景观时,碎片重新出现.标签布局也有错误,没有滑动动画,我可以从一个标签连续滑动到另一个标签,停在任何地方.

为了澄清事情,这发生在一个Activity中,没有父片段.即使未显示片段,onViewCreated也会调用片段.视图寻呼机似乎正确恢复了片段引用instantiateItem.此外,在调试时,片段具有addedtrue和hiddenfalse.这使它看起来像一个视图寻呼机渲染问题.

  • 如何让视图寻呼机显示我的片段?
  • 有没有更好的方法来实现我想要的行为?

Nic*_*las 3

我发现的解决方案非常简单,getPageWidth在我的寻呼机适配器中覆盖,如下所示:

@Override
public float getPageWidth(int position) {
    boolean hasTwoPanes = getResources().getBoolean(R.bool.hasTwoPanes);
    return hasTwoPanes ? 0.5f : 1.0f;
}
Run Code Online (Sandbox Code Playgroud)

R.bool.hasTwoPanes是默认配置中可用的布尔资源values-land。我的布局对于两种配置都是相同的,并且选项卡布局只是隐藏在横向上。

片段恢复由视图分页器自动完成。