TabLayout的使用,轻松实现带标题头的ViewPager

实现ViewPager+TabLayout实现带标题头的ViewPager

Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件。最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2。这不得不说是一个良心之作。

使用方法很简单,只需要添加一句依赖

compile 'com.android.support:design:24.2.0'

Tab滑动切换View并不是一个新的概念,但是Google却是第一次在support库中提供了完整的支持,
而且,Design library的TabLayout 既实现了固定的选项卡 - view的宽度平均分配,
也实现了可滚动的选项卡 - view宽度不固定同时可以横向滚动。选项卡可以在程序中动态添加,
但大部分时间我们都不会这样用,通常滑动布局都会和ViewPager配合起来使用,所以,我们需要ViewPager来帮忙:
通过一句话setupWithViewPager,我们就把ViewPager和TabLayout结合了起来。

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;

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

/**
 *  标题头与ViewPager的结合
 */
public class MainActivity extends FragmentActivity {

    /**
     * 显示标题的
     */
    private TabLayout title;

    /**
     * 显示内容的ViewPager,来实现与标题的对应
     */
    private ViewPager viewPager;

    private List<String> titleList;//标题头的数据

    private List<Fragment> fragmentList;//ViewPager显示的Fragment

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        title = (TabLayout) findViewById(R.id.tl_title);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        initData();
        title.setupWithViewPager(viewPager);//将标题头TabLayout与ViewPager绑定 如果报错 和下面的换下位置
        viewPager.setAdapter(new MyAdapter(getSupportFragmentManager(),titleList,fragmentList));
    }

    /**
     * 初始化数据
     */
    private void initData() {
        //设置标题头数据
        titleList = new ArrayList<String>();
        titleList.add("推荐1");
        titleList.add("排行22");
        titleList.add("歌单333");
        titleList.add("电台4444");
        titleList.add("糗事55555");
        titleList.add("百科666666");
        //设置Fragment数据
        fragmentList = new ArrayList<Fragment>();
        for (String title : titleList) {
            MyFragment myFragment = new MyFragment();
            Bundle bundle = new Bundle();
            bundle.putString("键",title);
            myFragment.setArguments(bundle);
            fragmentList.add(myFragment);
        }
    }
}

 适配器MyAdapter:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.List;

/**
 * ViewPager的适配器
 */
public class MyAdapter extends FragmentPagerAdapter {

    private List<String> titleList;//标题头的数据

    private List<Fragment> fragmentList;//ViewPager显示的Fragment


    public MyAdapter(FragmentManager fm, List<String> titleList, List<Fragment> fragmentList) {
        super(fm);
        this.titleList = titleList;
        this.fragmentList = fragmentList;
    }

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

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


    /**
     * 将标题头显示的数据与ViewPager进行绑定
     */
    @Override
    public CharSequence getPageTitle(int position) {
        return titleList.get(position);
    }
}

ViewPager显示的布局MyFragment

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * ViewPager每个页面的碎片
 */
public class MyFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_layout, container, false);
        TextView textView = (TextView) view.findViewById(R.id.textView);
        String value = getArguments().getString("键","默认");
        textView.setText(value);
        return view;
    }
}

activity_main.xml

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

    <!--  标题头的设置
        app:tableIndicatorColor = "#0000ff" 设置下划线的颜色
        app:tabTextColor="#000000"        设置文本颜色
        app:tabSelectedTextColor="#0000ff" 设置选中的文本的颜色
        app:tabMode="scrollable"
            模式1: scrollable 当标题头长度超过屏宽时,可以横向滚动
            模式2: fixed 填充,宽度平均分配,标题头不能滚动
               -->
    <android.support.design.widget.TabLayout
        android:id="@+id/tl_title"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:background="#ffffff"
        app:tabIndicatorColor="#0000ff"
        app:tabTextColor="#000000"
        app:tabSelectedTextColor="#0000ff"
        app:tabMode="scrollable">
    </android.support.design.widget.TabLayout>

    <!--利用ViewPager来显示与标题对应的内容-->
    <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>

Fragment显示的布局,fragment_layout.xml

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

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/textView"
            android:textSize="50sp"
            android:text="显示的内容"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>

</LinearLayout>

效果图: 下面的蓝色线条还可以跟着滑动 

  

 改变文本大小: 对应大中小

app:tabTextAppearance="@android:style/TextAppearance.Holo.Large"

<style name="TextAppearance.Holo.Large" parent="TextAppearance.Large" />

<style name="TextAppearance.Holo.Medium" parent="TextAppearance.Medium" />

<style name="TextAppearance.Holo.Small" parent="TextAppearance.Small" />

 也可以:

style="@style/MyCustomTabLayout"  //为Tablayout设置样式

<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
        <item name="tabTextAppearance">@style/MyCustomTabTextAppearance</item>
    </style>

    <!--设置字体大小-->
    <style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
        <item name="android:textSize">25sp</item>
        <item name="textAllCaps">false</item>
    </style>

 

但有时候我们的tab需要是图片加文字的,那就只能这样搞了:

public class MainActivity extends AppCompa

    private TabLayout tabLayout;
    private ViewPager viewPager;


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

        //数据源
        String[] titles = {"第一个","第二个","第三个"};
        int[] imgs = {R.drawable.selector_tab_image, R.drawable.selector_tab_image, R.drawable.selector_tab_image};


        tabLayout = (TabLayout ) findViewById(R.id.tl_title);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        MyAdapter myAdapter = new MyAdapter(getSupportFragmentManager());
        viewPager.setAdapter(myAdapter);
        tabLayout.setupWithViewPager(viewPager);//与ViewPager关联

        //设置数据 并先选择第一个tab
        for (int i = 0; i < myAdapter.getCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);//获得每一个tab
            tab.setCustomView(R.layout.tab_item);//给每一个tab设置view
            if (i == 0) {
                // 设置第一个tab的item是被选择的样式
                tab.getCustomView().findViewById(R.id.tab_text).setSelected(true);
                tab.getCustomView().findViewById(R.id.tab_img).setSelected(true);
            }
            //动态的为每个Tab设置文本与内容
            TextView textView = (TextView) tab.getCustomView().findViewById(R.id.tab_text);
            textView.setText(titles[i]);//设置tab上的文字
            ImageView imageView = (ImageView) tab.getCustomView().findViewById(R.id.tab_img);
            imageView.setImageResource(imgs[i]);//设置tab上的图像

        }

        //Tab选择的监听
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //显示现在选择的
                tab.getCustomView().findViewById(R.id.tab_text).setSelected(true);
                tab.getCustomView().findViewById(R.id.tab_img).setSelected(true);
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                //隐藏之前选择的
                tab.getCustomView().findViewById(R.id.tab_text).setSelected(false);
                tab.getCustomView().findViewById(R.id.tab_img).setSelected(false);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                //再次选择
            }
        });

    }


    /**
     * ViewPager的适配器, 因为Tab为自定义了  所以这里不需要重写getPageTitle()方法
     */
    public class MyAdapter extends FragmentPagerAdapter {

        private List<Fragment> fragmentList;//ViewPager显示的Fragment

        public MyAdapter(FragmentManager fm) {
            super(fm);
            //设置Fragment数据
            fragmentList = new ArrayList<>();
            MyFragment myFragment1 = new MyFragment();
            fragmentList.add(myFragment1);
            MyFragment myFragment2 = new MyFragment();
            fragmentList.add(myFragment2);
            MyFragment myFragment3 = new MyFragment();
            fragmentList.add(myFragment3);
        }

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

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

    }
}

布局文件:

<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--tabIndicatorHeight 设置指示器的高度  不需要设置为0就行了-->
    <android.support.design.widget.TabLayout
        android:id="@+id/tl_title"
        android:layout_height="80dp"
        android:layout_width="match_parent"
        android:background="#ffffff"
        app:tabIndicatorColor="#0000ff"
        app:tabIndicatorHeight="5dp"
        app:tabMode="fixed">
    </android.support.design.widget.TabLayout>


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

</LinearLayout>

Tab的item布局:

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

    <!--文本与图片大小都是可控的-->
    <ImageView
        android:id="@+id/tab_img"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:scaleType="fitXY"
        android:src="@drawable/selector_tab_image" />

    <TextView
        android:id="@+id/tab_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是文本"
        android:textSize="15sp"
        android:textColor="@color/selector_tab_text" />
</LinearLayout>

图片与文本的选择器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/ic_launcher" android:state_selected="true" />
    <item android:drawable="@drawable/b10399_4" android:state_selected="false" />
</selector>


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#F00" android:state_selected="true" />
    <item android:color="#0FF" android:state_selected="false" />
</selector>

效果如下: 滑动ViewPager时 TabLayout可以跟着联动 如果不需要指示器设置高度为0就噢了

 

TabLayout单独使用,另一种添加标题头的实现:

    //添加标题头
        TabLayout.Tab tab1 = tabLayout.newTab().setText("商品");
        tabLayout.addTab(tab1,true);//true 被选中状态
        TabLayout.Tab tab2 = tabLayout.newTab().setText("详情");
        tabLayout.addTab(tab2);
        //设置选中监听
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                ToastUtils.showToast("选中的:" + tab.getText().toString());
            }

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

            }

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

            }
        });

效果如下:

 

不绑定ViewPager 单独设置tabLayout的Item

binding.tabLayout.removeAllTabs()
        val newTab = binding.tabLayout.newTab()
        newTab.setCustomView(R.layout.publish_item_tshirts_tab)
        newTab.customView?.findViewById<TextView>(R.id.tvTabTitle)?.text = "正面"
        val antiTabItem = binding.tabLayout.newTab()
        antiTabItem.setCustomView(R.layout.publish_item_tshirts_tab)
        antiTabItem.customView?.findViewById<TextView>(R.id.tvTabTitle)?.text = "反面"
        binding.tabLayout.addTab(newTab, true)
        binding.tabLayout.addTab(antiTabItem, false)
        binding.tabLayout.clearOnTabSelectedListeners()

 

posted @ 2016-10-05 22:26  ts-android  阅读(2301)  评论(0编辑  收藏  举报