<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>
1. 禁止重復添加相同的Fragment到Viewpager中
當時,我的tab有三個,但是另外兩個Fragment還沒有寫好,就偷懶把FragmentPagerAdapter中數組重復添加了第一個fragment三次,結果就出錯了:
Can't change tag of fragment SubscribedFragment{41157420 id=0x7f070005 android:switcher:2131165189:0}: was android:switcher:2131165189:0 now android:switcher:2131165189:1
解決方法
新建另外的兩個Fragment,與FragmentPagerAdapter綁定。
2. setupWithViewPager后Tab不顯示
查看源碼:
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>
注意 addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false); ,看到沒,在setupWithViewPager后,會自動添加三個Tab,Tab上的文字是FragmentPagerAdapter中的PageTitle。
所以,我們不能自己給TabLayout添加tab,因為你只要綁定ViewPager,它會自動再添加一次。
2.1 那么怎么來讓Tab顯示文字和圖標呢?
如果只顯示文字可以直接在定義FragmentPagerAdapter時,添加一個方法就行:
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>
因為 FragmentPagerAdapter 中無法指定圖標,所以,我們可以在執行完 setupWithViewPager 后,給已經添加上的tab重新設置:
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);
注意
可以看到 setIcon 的參數為xml,這樣就可以實現點擊后圖標變色了。
<?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>
這就很簡單了,去掉 setText 就可以:
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);
3. 完整的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>
Enjoy Coding! 如果在閱讀本博客的過程中有任何疑問或者需要幫助,可以隨時在微博上聯系我,我的微博是@orzanglei。
來自:http://www.orzangleli.com/2017/02/17/2017-02-17_ViewPager Fragment TabLayout爬坑/