ViewPager+Fragment+TabLayout 爬坑
q21syj
8年前
<pre> <code class="language-java"><?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.orzangleli.xiaoxiannv.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" ></android.support.v4.view.ViewPager> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="60dp" android:background="@color/titleBlue" app:tabIndicatorColor="@color/white" app:tabIndicatorHeight="2dp" app:tabMode="fixed" app:tabSelectedTextColor="@color/white" app:tabTextColor="@color/gray" /> </LinearLayout> </android.support.constraint.ConstraintLayout> </code></pre> <h2>1. 禁止重复添加相同的Fragment到Viewpager中</h2> <p>当时,我的tab有三个,但是另外两个Fragment还没有写好,就偷懒把FragmentPagerAdapter中数组重复添加了第一个fragment三次,结果就出错了:</p> <p>Can't change tag of fragment SubscribedFragment{41157420 id=0x7f070005 android:switcher:2131165189:0}: was android:switcher:2131165189:0 now android:switcher:2131165189:1</p> <p>解决方法</p> <p>新建另外的两个Fragment,与FragmentPagerAdapter绑定。</p> <h2>2. setupWithViewPager后Tab不显示</h2> <p>查看源码:</p> <pre> <code class="language-java">voidpopulateFromPagerAdapter(){ removeAllTabs(); if (mPagerAdapter != null) { final int adapterCount = mPagerAdapter.getCount(); for (int i = 0; i < adapterCount; i++) { addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false); } // Make sure we reflect the currently set ViewPager item if (mViewPager != null && adapterCount > 0) { final int curItem = mViewPager.getCurrentItem(); if (curItem != getSelectedTabPosition() && curItem < getTabCount()) { selectTab(getTabAt(curItem)); } } } } </code></pre> <p>注意 addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false); ,看到没,在setupWithViewPager后,会自动添加三个Tab,Tab上的文字是FragmentPagerAdapter中的PageTitle。</p> <p>所以,我们不能自己给TabLayout添加tab,因为你只要绑定ViewPager,它会自动再添加一次。</p> <h3>2.1 那么怎么来让Tab显示文字和图标呢?</h3> <ul> <li>只显示文字</li> </ul> <p>如果只显示文字可以直接在定义FragmentPagerAdapter时,添加一个方法就行:</p> <pre> <code class="language-java">pageAdapter = new FragmentPagerAdapter(this.getSupportFragmentManager()) { @Override publicFragmentgetItem(intposition){ return fragmentList.get(position); } @Override publicintgetCount(){ return fragmentList.size(); } @Override publicCharSequencegetPageTitle(intposition){ return mTitles[position]; } }; </code></pre> <ul> <li>显示文字和图标</li> </ul> <p>因为 FragmentPagerAdapter 中无法指定图标,所以,我们可以在执行完 setupWithViewPager 后,给已经添加上的tab重新设置:</p> <pre> <code class="language-java">tabLayout.setupWithViewPager(viewPager); tabLayout.getTabAt(0).setText(mTitles[0]).setIcon(R.drawable.home_xml); tabLayout.getTabAt(1).setText(mTitles[1]).setIcon(R.drawable.rank_xml); tabLayout.getTabAt(2).setText(mTitles[2]).setIcon(R.drawable.category_xml); </code></pre> <p>注意</p> <p>可以看到 setIcon 的参数为xml,这样就可以实现点击后图标变色了。</p> <pre> <code class="language-java"><?xml version="1.0" encoding="utf-8"?> <selectorxmlns:android="http://schemas.android.com/apk/res/android"> <itemandroid:drawable="@drawable/home2"android:state_selected="true"/> <itemandroid:drawable="@drawable/home"/> </selector> </code></pre> <ul> <li>只显示图标</li> </ul> <p>这就很简单了,去掉 setText 就可以:</p> <pre> <code class="language-java">tabLayout.setupWithViewPager(viewPager); tabLayout.getTabAt(0).setIcon(R.drawable.home_xml); tabLayout.getTabAt(1).setIcon(R.drawable.rank_xml); tabLayout.getTabAt(2).setIcon(R.drawable.category_xml); </code></pre> <h2>3. 完整的java 代码</h2> <pre> <code class="language-java">public classMainActivityextendsAppCompatActivity{ private String[] mTitles = new String[]{"首页", "排行","分类"}; TabLayout tabLayout; ViewPager viewPager; List<Fragment> fragmentList; FragmentPagerAdapter pageAdapter; @Override protectedvoidonCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tabLayout = (TabLayout)this.findViewById(R.id.tabLayout); viewPager = (ViewPager)this.findViewById(R.id.viewPager); initFragment(); initAdapter(); tabLayout.setupWithViewPager(viewPager); tabLayout.getTabAt(0).setText(mTitles[0]).setIcon(R.drawable.home_xml); tabLayout.getTabAt(1).setText(mTitles[1]).setIcon(R.drawable.rank_xml); tabLayout.getTabAt(2).setText(mTitles[2]).setIcon(R.drawable.category_xml); } privatevoidinitAdapter(){ pageAdapter = new FragmentPagerAdapter(this.getSupportFragmentManager()) { @Override publicFragmentgetItem(intposition){ return fragmentList.get(position); } @Override publicintgetCount(){ return fragmentList.size(); } @Override publicCharSequencegetPageTitle(intposition){ return mTitles[position]; } }; viewPager.setAdapter(pageAdapter); } privatevoidinitFragment(){ fragmentList = new ArrayList<Fragment>(); RecentPostsFragment recentPostsFragment = new RecentPostsFragment(); RankFragment rankFragment = new RankFragment(); CategoryFragment categoryFragment = new CategoryFragment(); //添加到数组中 fragmentList.add(recentPostsFragment); fragmentList.add(rankFragment); fragmentList.add(categoryFragment); } } </code></pre> <p>Enjoy Coding! 如果在阅读本博客的过程中有任何疑问或者需要帮助,可以随时在微博上联系我,我的微博是@orzanglei。</p> <p> </p> <p>来自:http://www.orzangleli.com/2017/02/17/2017-02-17_ViewPager Fragment TabLayout爬坑/</p> <p> </p>