TabLayout 的使用

    以前我们要实现想腾讯视频,网易新闻的选项卡动态效果大多数都是使用自定义的 ViewPagerIndicator 配合ViewPager 。但谷歌推出 TabLayout 后,只需要使用的时候导入 design 包即可
        implementation 'com.android.support:design:26.1.0'

    一、 先实现布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabBackground="@color/white_FFFFFF"
        app:tabIndicatorColor="@color/select_color_000000"
        app:tabIndicatorHeight="@dimen/indicator_height_2dp"
        app:tabMode="fixed"
        app:tabTextAppearance="@style/TabLayoutTextStyle"
        app:tabSelectedTextColor="@color/select_color_000000"
        app:tabTextColor="@color/color_999999">

    </android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>

</LinearLayout>

    这里解释一下TabLayout 的一些属性:

    tabBackground : 标签栏的颜色

    tabIndicatorColor : 指示条的颜色

    tabIndicatorHeight : 指示条的高度

    tabMode  : 选项卡的行为模式  两种模式。一种是 scrollable  适用于当标签栏的数量多的时候,标签栏可以滑动,经个人测试,一般是标签栏5个以上适用于这个模式  第二种是 fixed 默认的设置,标签栏是固定的,不能滑动,很多的时候会发生挤压,当标签栏的个数小于等于5个的时候选择这个模式就很不错。

    tabSelectedTextColor : tab 被选中的时候的字体颜色

    tabTextColor : tab 未被选中的时候的字体的颜色

    tabTextAppearance :  设置字体的外观。 比如说设置字体的大小 

    <style name="TabLayoutTextStyle">
        <item name="android:textSize">@dimen/text_16_sp</item>
        <item name="android:textAllCaps">false</item>
    </style>

    二、OK,下面开始通过代码实现:

    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private List<String> titles = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tablayout);
        intData();
        initView();
        initEvent();
    }

    private void intData() {
        titles.add("电影");
        titles.add("电视剧");
        titles.add("综艺");
    }

    private void initView() {
        mTabLayout = (TabLayout) findViewById(R.id.tablayout);
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
    }

    private void initEvent() {
        for (int i = 0; i < titles.size(); i++) {
            mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(i)));
        }
        List<Fragment> fragments = new ArrayList<Fragment>();
        for (int i = 0; i < titles.size(); i++) {
            fragments.add(new MyFragment());
        }
        MyFragmentPager fragmentPager = new MyFragmentPager(getSupportFragmentManager(), fragments, titles);
        // 给ViewPager 设置适配器
        mViewPager.setAdapter(fragmentPager);
        //  将TabLayout 和 ViewPager 关联起来
        mTabLayout.setupWithViewPager(mViewPager);
    }
    因为要使用ViewPager,首先要自定义一个Fragment,我自定义了一个Fragment ,代码如下:
public class MyFragment extends Fragment {
    View view;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_tablayout, container, false);
        return view;
    }
}

  其中fragment_tablayout.xml 里面只是有一个TextView。

扫描二维码关注公众号,回复: 1959968 查看本文章
<?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"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="总有一个人让你拼了命的努力变好!"
        android:textSize="20dp" />
</LinearLayout>

    然后我们在主界面也自定义定义了一个MyFragmentPager,用于配合ViewPager 管理Fragment,代码如下:

public class MyFragmentPager extends FragmentStatePagerAdapter {

    List<Fragment> mFragments;
    List<String> mTitles;

    public MyFragmentPager(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
        super(fm);
        mFragments = fragments;
        mTitles = titles;
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

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

    /**
     * 设置标签栏的标题
     *
     * @param position
     * @return
     */
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitles.get(position);
    }
}

    这个特别要注意一下getPagerTitle 方法,这里返回position 位置的PagerTab 的标题。跑下代码,效果如图:

    好了,上面就是tabLayout 配合ViewPager的基本使用了,下面我们扩展下。像网易云音乐的标签栏,并没有使用文字标题,而是使用的图片,那么我们怎样利用tabLayout的时候也使用图片呢?  我上面提到过 getPagerTitle() 方法,这个方法的返回的类型是 CharSequence。我们可以创建一个SpannableString,将图片放置在ImageSpan 中,设置在SpannableString中,我们改下MyFragmentPager 的代码:

public class MyFragmentPager extends FragmentStatePagerAdapter {

    List<Fragment> mFragments;
    List<String> mTitles;
    Context mContext;
    int[] mImages;

    public MyFragmentPager(Context context, FragmentManager fm, List<Fragment> fragments,
                           List<String> titles, int[] images) {
        super(fm);
        mFragments = fragments;
        mTitles = titles;
        mContext = context;
        mImages = images;
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

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

    /**
     * 设置标签栏的标题
     *
     * @param position
     * @return
     */
    @Override
    public CharSequence getPageTitle(int position) {
        Drawable image = ContextCompat.getDrawable(mContext, mImages[position]);
        image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
        SpannableString sb = new SpannableString(" ");
        ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
        sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return sb;
    }
}
    可以看到我们的这个MyFragmentPager 的构造函数发生了变化,而此时我们也要更改下主界面的传参,代码如下:
    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private int[] images;
    private List<String> titles = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tablayout);
        intData();
        initView();
        initEvent();
    }

    private void intData() {
        titles.add("电影");
        titles.add("电视剧");
        titles.add("综艺");
        images = new int[]{R.mipmap.teleplay, R.mipmap.movie, R.mipmap.shows};
    }

    private void initView() {
        mTabLayout = (TabLayout) findViewById(R.id.tablayout);
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
    }

    private void initEvent() {
        for (int i = 0; i < titles.size(); i++) {
            mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(i)));
        }
        List<Fragment> fragments = new ArrayList<Fragment>();
        for (int i = 0; i < titles.size(); i++) {
            fragments.add(new MyFragment());
        }
        MyFragmentPager fragmentPager = new MyFragmentPager(this, getSupportFragmentManager(), fragments, titles, images);
        // 给ViewPager 设置适配器
        mViewPager.setAdapter(fragmentPager);
        //  将TabLayout 和 ViewPager 关联起来
        mTabLayout.setupWithViewPager(mViewPager);
    }

   这里是那三个图片的资源:    电影     电视剧    综艺   ,效果如下:

    有时候客户可能并不满足于这样简单的样式,而是想要在TabLayout 的标签上展现各式各样的内容,这时候我们就需要自定义View 来实现了。TabLayout 中有一个方法 setCustomView(),可以通过调用这个方法来加载我们自定义的View,进而实现我们想要的各式各样的标签。OK,我们先自定义一个Tab 的样式,创建一个 item_tab_style.xml 文件,图片在上,文字在下:

<?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"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/iv_tab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/movie" />

    <TextView
        android:id="@+id/tv_tab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="电影"
        android:textSize="@dimen/text_16_sp" />

</LinearLayout>

    然后在代码中将这个布局加载进去,完整的代码如下:

    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private int[] images;
    private List<String> titles = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tablayout);
        intData();
        initView();
        initEvent();
    }

    private void intData() {
        titles.add("电影");
        titles.add("电视剧");
        titles.add("综艺");
        images = new int[]{R.mipmap.teleplay, R.mipmap.movie, R.mipmap.shows};
    }

    private void initView() {
        mTabLayout = (TabLayout) findViewById(R.id.tablayout);
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
    }

    private void initEvent() {
        for (int i = 0; i < titles.size(); i++) {
            mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(i)));
        }
        List<Fragment> fragments = new ArrayList<Fragment>();
        for (int i = 0; i < titles.size(); i++) {
            fragments.add(new MyFragment());
        }
        MyFragmentPager fragmentPager = new MyFragmentPager(this, getSupportFragmentManager(), fragments, titles, images);
        // 给ViewPager 设置适配器
        mViewPager.setAdapter(fragmentPager);
        //  将TabLayout 和 ViewPager 关联起来
        mTabLayout.setupWithViewPager(mViewPager);

        for (int i = 0; i < titles.size(); i++) {
            mTabLayout.getTabAt(i).setCustomView(getTabView(i));
        }

        // 添加TabLayout 的监听
        mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                changeTabStatus(tab, true);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                changeTabStatus(tab, false);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }

    /**
     * 获取自定义布局
     *
     * @param postion
     * @return
     */
    private View getTabView(final int postion) {
        final View view = LayoutInflater.from(this).inflate(R.layout.item_tab_style, null);
        ImageView ivTab = (ImageView) view.findViewById(R.id.iv_tab);
        TextView tvTab = (TextView) view.findViewById(R.id.tv_tab);
        ivTab.setImageDrawable(ContextCompat.getDrawable(this, images[postion]));
        tvTab.setText(titles.get(postion));
        return view;
    }

    /**
     * 在标签页状态改变的时候更改状态
     *
     * @param tab
     * @param selected
     */
    private void changeTabStatus(TabLayout.Tab tab, boolean selected) {
        View view = tab.getCustomView();
        final ImageView imgTitle = (ImageView) view.findViewById(R.id.iv_tab);
        TextView txtTitle = (TextView) view.findViewById(R.id.tv_tab);
        imgTitle.setVisibility(View.VISIBLE);
        if (selected) {
            txtTitle.setTextColor(getResources().getColor(R.color.select_color_000000));
        } else {
            txtTitle.setTextColor(getResources().getColor(R.color.color_999999));
        }
    }

    这样就实现了标签自定义View,最后看一下我们的实现效果:

    好了,上面就是tabLayout 的一些具体的实现。


猜你喜欢

转载自blog.csdn.net/javasxl/article/details/80467144