代码之家  ›  专栏  ›  技术社区  ›  Nicolas

VIEWPAGER(纵向)和两个窗格(横向)

  •  9
  • Nicolas  · 技术社区  · 6 年前

    我正在尝试实现这样一种布局:当设备以纵向方式显示时,显示视图寻呼机;当设备以横向方式显示时,显示两个窗格。

    所以我制作了两个不同的布局文件,一个只有viewpager,另一个有linearlayout,另一个有两个framelayouts,我不认为有必要在这里显示它们。还有一个布尔值 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;
    }
    

    两块碎片被注入匕首。如果没有片段已经存在,这些注入的片段将根据方向添加到视图页导航或布局中。

    因为视图寻呼机适配器为其片段提供了一个名称,所以我需要知道该名称(因此 getFragmentName(int pos) 方法)在旋转后取回碎片。

    结果是,当从纵向旋转到横向时,状态会正确恢复,但当从横向旋转纵向时,视图寻呼机完全为空。当我旋转回景观,碎片重新出现。选项卡布局也很麻烦,没有滑动动画,我可以从一个选项卡连续滑动到另一个选项卡,在任何地方停止。

    为了澄清问题,这发生在一个活动中,没有父片段。即使没有显示片段,片段的 onViewCreated 被调用。视图页导航似乎正确地还原了中的片段引用 instantiateItem . 此外,在调试时,片段具有 added 为真和 hidden 错误。这使得它看起来像一个视图寻呼机渲染问题。

    • 如何使视图传呼机显示我的片段?
    • 有没有更好的方法来实现我想要的行为?
    3 回复  |  直到 6 年前
        1
  •  3
  •   Chapz    6 年前

    你试过用pageradapter代替fragmentpageradapter吗?您将更好地控制片段的创建和处理。否则你就不知道fragmentpageradapter在做什么(他是为你做的,但可能是错的)。

    您可以将大部分逻辑移动到该类中,从而使活动更干净,并且可能还可以修复您所遇到的问题。

    编辑:既然我们在讨论方向改变,你可能应该 onConfigurationChanged 回调以更好地处理该逻辑。

        2
  •  3
  •   Nicolas    6 年前

    getPageWidth 在我的寻呼机适配器中,如下所示:

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

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

    片段恢复由视图寻呼机自动完成。

        3
  •  2
  •   Manoj Singh Rawal    6 年前

    试试这个

    纵向XML:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>
    

    横向XML:

     <?xml version="1.0" encoding="utf-8"?>
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        <FrameLayout
            android:id="@+id/fragmentA"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />
        <FrameLayout
            android:id="@+id/fragmentB"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>
    

    活动Java:

    package com.dev4solutions.myapplication;
    
    import android.graphics.Point;
    import android.os.Bundle;
    import android.support.design.widget.TabLayout;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    
    import com.dev4solutions.myapplication.fragment.FragmentA;
    import com.dev4solutions.myapplication.fragment.FragmentB;
    
    public class FragmentActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Point point = new Point();
            getWindowManager().getDefaultDisplay().getSize(point);
            setContentView(R.layout.activity_frag);
            if (point.y > point.x) {
                TabLayout tabLayout = findViewById(R.id.tab);
                ViewPager viewPager = findViewById(R.id.pager);
                tabLayout.setupWithViewPager(viewPager);
                viewPager.setAdapter(new PagerAdapter(getSupportFragmentManager()));
    
            } else {
                getSupportFragmentManager()
                        .beginTransaction()
                        .add(R.id.fragmentA, new FragmentA())
                        .commit();
                getSupportFragmentManager()
                        .beginTransaction()
                        .add(R.id.fragmentB, new FragmentB())
                        .commit();
            }
        }
    }
    
    推荐文章