文章大纲

  • 引言
  • 一、使用TabLayout的项目配置
  • 二、结合ViewPager+Fragment打造绚丽的Tabs切换页面
  • 1、首先,还是定义MainActivity的主布局和Fragment对应的布局(略)
  • 2、然后初始化ViewPagerAdapter和ViewPager
  • 3、接着,初始化TabLayout,包括设置一些属性和添加Tab
  • 4、**再把ViewPager和TabLayout管理起来**
  • 5、再把ViewPager的适配器设置到TabLayout上
  • 6、设置Tab事件监听
  • 7、完整MainActivity的实现
  • 三、 运行结果
  • 1、初始化进入到主界面时
  • 2、 滑动TAB1到TAB2时
  • 3、 往回滑动TAB3到TAB2时
  • 四、TabLayout的不常见错误及处理方案
  • 1、提示res下某些属性找不到
  • 2、java.lang.NoClassDefFoundError:android.support.v7.internal.widget.TintManager
  • 3、空指针异常
  • 小结


引言

上一篇总结讲解了下TabLayout的基本特点、属性和简单的应用步骤,相信大家已经对于TabLayout已经不再陌生,这篇就结合Fragment+ViewPager的架构开发一个主流App的主要框架,进一步学习下TabLayout的操作和监听,同时分享一些注意事

一、使用TabLayout的项目配置

要使用android.support.design.widget.TabLayout ,需要在自己的工程项目中引入Android的两个库android.support.design.widget.TabLayout在Android扩展(extras)支持(support)包design中,但是design又依赖另外一个support v7包中的appcompat库,因此需要事先导入。Android Studio的添加依赖库很简单,我只需要在我们Module的build.gradle脚本文件中添加如下的(PS:这是使用Android Studio1.4开发的,如果你还使用着Eclipse那么第一步你应该换成Android Studio)

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:support-v4:23.1.1'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

二、结合ViewPager+Fragment打造绚丽的Tabs切换页面

1、首先,还是定义MainActivity的主布局和Fragment对应的布局(略)

<?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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">
    <android.support.design.widget.TabLayout
        android:id="@+id/id_tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        app:tabGravity="center"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/id_viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#ffffff"
        />
</LinearLayout>

2、然后初始化ViewPagerAdapter和ViewPager

private ViewPagerAdapter mAdapter;
private List<Fragment> mFragments=new ArrayList<Fragment>();
//初始化ViewPagerAdapter
MainFragment mainTab = new MainFragment();
DiscoveryFragment discTab = new DiscoveryFragment();
Tab3Fragment tab3Fragment=new Tab3Fragment();
Tab4Fragment tab4Fragment=new Tab4Fragment();
Tab5Fragment tab5Fragment=new Tab5Fragment();
Tab6Fragment tab6Fragment=new Tab6Fragment();

mFragments.add(mainTab);
mFragments.add(discTab);
mFragments.add(tab3Fragment);
mFragments.add(tab4Fragment);
mFragments.add(tab5Fragment);
mFragments.add(tab6Fragment);
//初始化ViewPager
mAdapter=new ViewPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mAdapter);

private class ViewPagerAdapter extends FragmentStatePagerAdapter{

        public ViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }
        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }
        @Override
        public int getCount() {
            return mFragments.size();
        }
        @Override
        public CharSequence getPageTitle(int position) {
            return mTabTitles[position];
        }
    }

3、接着,初始化TabLayout,包括设置一些属性和添加Tab

private static String[] mTabTitles={"Tab1","Tab2","Tab3","Tab4","Tab5","Tab6"};

mTabLayout.setTabMode(TabLayout.MODE_FIXED);
mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
mTabLayout.setBackgroundColor(Color.parseColor("#2b2b2b"));
mTabLayout.setTabTextColors(Color.parseColor("#236f28"), Color.parseColor("#bc6e1c"));mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[0]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[1]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[2]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[3]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[4]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[5]));

4、再把ViewPager和TabLayout管理起来

mTabLayout.setupWithViewPager(mViewPager);//mViewPager必须非null

5、再把ViewPager的适配器设置到TabLayout上

mTabLayout.setTabsFromPagerAdapter(mAdapter);

6、设置Tab事件监听

//设置Tab监听
        mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.d("TAG","Selected Tab Index为:"+tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.d("TAG","Unselected Tab Index为:"+tab.getPosition());
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.d("TAG","Reselected Tab Index为:"+tab.getPosition());
            }
        });

7、完整MainActivity的实现

package com.crazymo.tablayoutviewpager;

import android.graphics.Color;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {
    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private ViewPagerAdapter mAdapter;
    private List<Fragment> mFragments = new ArrayList<Fragment>();
    private static String[] mTabTitles = {"Tab1", "Tab2", "Tab3", "Tab4", "Tab5", "Tab6"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    //初始化
    private void init() {
        getView();
        initTab();
    }

    //找到View
    private void getView() {
        mTabLayout = (TabLayout) findViewById(R.id.id_tabLayout);
        mViewPager = (ViewPager) findViewById(R.id.id_viewPager);
    }

    //初始化Tab
    private void initTab() {
        MainFragment mainTab = new MainFragment();
        DiscoveryFragment discTab = new DiscoveryFragment();
        Tab3Fragment tab3Fragment = new Tab3Fragment();
        Tab4Fragment tab4Fragment = new Tab4Fragment();
        Tab5Fragment tab5Fragment = new Tab5Fragment();
        Tab6Fragment tab6Fragment = new Tab6Fragment();

        mFragments.add(mainTab);
        mFragments.add(discTab);
        mFragments.add(tab3Fragment);
        mFragments.add(tab4Fragment);
        mFragments.add(tab5Fragment);
        mFragments.add(tab6Fragment);
        //设置TabLayout的一系列属性
        mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
        mTabLayout.setBackgroundColor(Color.parseColor("#2b2b2b"));
        mTabLayout.setTabTextColors(Color.parseColor("#236f28"), Color.parseColor("#bc6e1c"));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[0]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[1]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[2]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[3]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[4]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[5]));

        mAdapter = new ViewPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mAdapter);
        mTabLayout.setupWithViewPager(mViewPager);
        mTabLayout.setTabsFromPagerAdapter(mAdapter);

        //设置Tab监听
        mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.e("TAG", "Selected Tab Index为:" + tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.e("TAG", "Unselected Tab Index为:" + tab.getPosition());
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.e("TAG", "Reselected Tab Index为:" + tab.getPosition());
            }
        });


    }

    private class ViewPagerAdapter extends FragmentStatePagerAdapter {

        public ViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            Log.e("TAG", "获取的Fragement的索引值为:" + position);
            return mFragments.get(position);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Log.e("TAG", "返回Tab的标题");
            return mTabTitles[position];
        }
    }
}

三、 运行结果

1、初始化进入到主界面时

android tablayout选中tab android.support.design.widget.tablayout_TabLayout


说明ViewPagerAdapter被执行了两次

android tablayout选中tab android.support.design.widget.tablayout_TabLayout_02

2、 滑动TAB1到TAB2时

仅仅触发的是Tab事件,TAB2到TAB3也是如此。

android tablayout选中tab android.support.design.widget.tablayout_ViewPager_03

3、 往回滑动TAB3到TAB2时

仅仅触发的是Tab事件,TAB3返回TAB2也是如此。

android tablayout选中tab android.support.design.widget.tablayout_Tab_04


按主页键之后再返回也并未触发任何Tab或者ViewPagerAdapter事件,并且还是返回到原来选中的页面。

android tablayout选中tab android.support.design.widget.tablayout_android_05

四、TabLayout的不常见错误及处理方案

1、提示res下某些属性找不到

在导入库过程中,如果某些res目录下的value值过高比如value-23(Android SDK 23)但不巧发生错误如提示说找不到某某值,可以整个删除掉,或者打开SDK下载最新的相关库

2、java.lang.NoClassDefFoundError:android.support.v7.internal.widget.TintManager

发生这个或者类似的,包里的某个类找不到,一般都是因为冲突了,解决办法之一就是,统一使用支持包的版本比如:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:support-v4:23.1.1'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

如果还不行就把该工程引入的library moudule的 suppor v4 v7t的版本也改成一致的

3、空指针异常

参照上一篇初始TabLayout的那两个方法的非空声明去排查。

public void setupWithViewPager(@NonNull ViewPager viewPager)	//设置与ViewPager关联起来,注:不允许传递空的ViewPager,否则会异常

public void setTabsFromPagerAdapter(@NonNull PagerAdapter adapter)//设置TabLayout的适配器,注:不允许传递空的PagerAdapter,否则会异常

小结

Android Material Design 滑动指示选项卡TabLayout,就是当用户在该TabLayout的选项卡子item中选择触摸时候,文字和下方的指示器横条滑动指示。