ViewPager+Fragment+TabLayout 爬坑

q21syj 8年前發布 | 21K 次閱讀 ViewPager Android開發 移動開發

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns:android="

<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爬坑/

 

 本文由用戶 q21syj 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!