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>