Android Material Design 之 TabLayout学习

在开发中,我们常常会遇到像网易新闻客户端的Tab的开发,如下图:

这里写图片描述

以往我们在实际开发中可能会使用第三方开源的PagerSlidingTabStrip或者ViewPagerindicator去实现类似的效果。但自从Material Design出世后,Google给我们提供了TabLayout去实现了,这里就是简单学习下TabLayout的使用。

首先,我们得保证更新支持库开发环境支持库至少22以上,如下图:

这里写图片描述

这里用的开发工具是AS,所以我们要在build.gradle中引用这个design这个库,如下图:

这里写图片描述

或者自己手动在build.gradle中配置

dependencies {
    compile 'com.android.support:design:23.1.1'
}

然后在布局中加入TabLayout就可以了:

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

    <android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.design.widget.TabLayout>

</RelativeLayout>

TabLayout中添加Tab很简单,直接调用addTab()就行:

package com.demo.richard.tablayoutdemo;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    private TabLayout mTablayout;

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

        mTablayout = (TabLayout) findViewById(R.id.tablayout);
        mTablayout.addTab(mTablayout.newTab().setText("新闻"));
        mTablayout.addTab(mTablayout.newTab().setText("娱乐"));
        mTablayout.addTab(mTablayout.newTab().setText("财经"));
    }

}

效果图:

这里写图片描述

这里我们是默认的TabLayout的风格,没有进行任何修改样式。其实,TabLayout谷歌自己推出来的东西,它肯定考虑了很多方面的。TabLayout我们可以自行修改选择颜色的字体,底下被选中横线的颜色等等…

  • tabIndicatorColor // 下方滚动的下划线颜色
  • tabSelectedTextColor // tab被选中后,文字的颜色
  • tabTextColor // tab默认的文字颜色
  • tabSelectedTextColor // tab被选中的文字颜色
  • tabBackground
  • tabIndicatorHeight

修改下样式:

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

    <android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        richard:tabIndicatorColor="#FF5544"
        richard:tabSelectedTextColor="#FF5544"
        richard:tabTextColor="#555555">
    </android.support.design.widget.TabLayout>

</RelativeLayout>

效果如下:

这里写图片描述

那这些Tab页上是否可以加小图片呢?

查看了下TabLayout中有一个setIcon的方法,来看下setIcon()添加的图片会是怎样。

        TabLayout.Tab tab1 = mTablayout.newTab();
        tab1.setIcon(R.mipmap.ic_launcher);
        tab1.setText("最新");
        mTablayout.addTab(tab1);

效果图如下:

这里写图片描述

添加的图标位于文字的上方,那如果我要设置位于图片的左边呢?怎么办?我找了一圈貌似好像没有找到设置图片位置

这里写图片描述

但是,我们可以发现它有一个setCustomView()方法,这表明,我们可以定制自己想要的布局,所以代如下:

新建一个icon_layout.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="horizontal">

    <ImageView
        android:id="@+id/img"
        android:layout_width="20dp"
        android:layout_height="20dp" />

    <TextView
        android:id="@+id/title_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity:

package com.demo.richard.tablayoutdemo;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TabLayout mTablayout;
    private String[] titleArra = new String[]{"最新", "娱乐", "财经", "体育"};

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

        mTablayout = (TabLayout) findViewById(R.id.tablayout);
        getTabView();

    }

    private void getTabView() {
        for(String str : titleArra){
            View view = LayoutInflater.from(this).inflate(R.layout.icon_layout, null);
            TextView tv = (TextView) view.findViewById(R.id.title_tv);
            ImageView imageView = (ImageView) view.findViewById(R.id.img);
            tv.setText(str);
            imageView.setImageResource(R.mipmap.ic_launcher);
            mTablayout.addTab(mTablayout.newTab().setCustomView(view));
        }
    }

}

效果图如下:

这里写图片描述

那么到这里我们可以知道通过setCustomView()可以去定制我们想要的TabTitle布局。

TabLayout中可以通过setTabMode()去设置Tab显示的模式

TabMode的2种模式
MODE_FIXED:固定选项卡显示所有选项卡的大小,平均分配(默认的模式)。
MODE_SCROLLABLE:可以延伸滚动,包含所有的选项卡,根据选项卡显示的内容来分配显示大小,适用于多选项卡

TabLayout.MODE_SCROLLABLE与TabLayout.MODE_FIXED效果对比如下

这里写图片描述 这里写图片描述

从上面的对比中很明显就能看出来,2种模式之间的区别。在这里特别提醒下,setTabGravity()这个方法只有在Mode为MODE_FIED下才有用。

在实际开发中的大部分情况下TabLayout基本上都不会单独去使用,一般我们会配合ViewPager来实现向网易新闻那样的切换效果,下面我们通过一个简单的demo来学习使用它。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:richard="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"
        richard:tabIndicatorColor="#FF5544"
        richard:tabSelectedTextColor="#FF5544"
        richard:tabTextColor="#555555"></android.support.design.widget.TabLayout>

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

</LinearLayout>

TabContentFragment

/**
 * Created by Richard on 2016/2/17.
 */
public class TabContentFragment extends Fragment {

    private String title;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        title = getArguments().getString("title");
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.icon_layout, container, false);

        TextView tv = (TextView) view.findViewById(R.id.title_tv);
        tv.setText(title);
        return view;
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {

    private TabLayout mTablayout;
    private ViewPager mViewPager;
    private TabTitlePager mTabTitleAdapter;

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

        mTablayout = (TabLayout) findViewById(R.id.tablayout);
        mTablayout.setTabMode(TabLayout.MODE_FIXED);

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mTabTitleAdapter = new TabTitlePager(getSupportFragmentManager());
        mViewPager.setAdapter(mTabTitleAdapter);
        mTablayout.setupWithViewPager(mViewPager);
    }



    public class TabTitlePager extends FragmentPagerAdapter{

        private String[] titleArr = new String[]{"全部","体育","娱乐","财经","养生"};

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

        @Override
        public Fragment getItem(int position) {
            TabContentFragment fragment = new TabContentFragment();
            Bundle bundle = new Bundle();
            bundle.putString("title", titleArr[position]);
            fragment.setArguments(bundle);
            return fragment;
        }

        @Override
        public int getCount() {
            return titleArr.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return titleArr[position];
        }
    }


}

效果图如下

这里写图片描述

可能到这里细心的朋友可能发现了,没有添加Tab的代码,怎么Title显示在上面呢!其实上面的Demo中,我使用的是ViewPager和TabLayout一站式管理Tab,没有手动添加Tab,所以我们要记得重写adapter中的一个方法getPageTitle(),因为getPageTitle自动帮我们添加Tab的过程进行了封装。

        @Override
        public CharSequence getPageTitle(int position) {
            return titleArr[position];
        }

那如果使用demo中的一站式管理,如果我要把Tab布局换成我自己想要定义的布局,怎么办?同理嘛!一个个给它加嘛!


public class MainActivity extends AppCompatActivity {

    private String[] titleArr = new String[]{"全部","体育","娱乐","财经","养生"};

    private TabLayout mTablayout;
    private ViewPager mViewPager;
    private TabTitlePager mTabTitleAdapter;

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

        mTablayout = (TabLayout) findViewById(R.id.tablayout);
        mTablayout.setTabMode(TabLayout.MODE_FIXED);

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mTabTitleAdapter = new TabTitlePager(getSupportFragmentManager());
        mViewPager.setAdapter(mTabTitleAdapter);
        mTablayout.setupWithViewPager(mViewPager);

        for(int i = 0; i < titleArr.length; i++){
            TabLayout.Tab tab = mTablayout.getTabAt(i);
            tab.setCustomView(mTabTitleAdapter.getTabView(i));
        }
    }


    public class TabTitlePager extends FragmentPagerAdapter{

        private LayoutInflater mInflater;

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

        @Override
        public Fragment getItem(int position) {
            TabContentFragment fragment = new TabContentFragment();
            Bundle bundle = new Bundle();
            bundle.putString("title", titleArr[position]);
            fragment.setArguments(bundle);
            return fragment;
        }

        @Override
        public int getCount() {
            return titleArr.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return titleArr[position];
        }


        public View getTabView(int position){
            mInflater = LayoutInflater.from(MainActivity.this);
            View view = mInflater.inflate(R.layout.icon_layout, null);
            TextView textView = (TextView) view.findViewById(R.id.title_tv);
            ImageView img = (ImageView) view.findViewById(R.id.img);
            img.setImageResource(R.mipmap.ic_launcher);
            textView.setText(titleArr[position]);
            return  view;
        }

    }


}

效果图

这里写图片描述

当然咯!如果你仅仅只想添加一个图片在Tab title的左边的话,那么你在getPageTitle()方法里使用SpannableString进行处理也是可以的,实现思路自己想嘛!哈哈…,多用用就知道怎么使用合适了。

在使用TabLayout中我们需要注意一些基本的方法

  • getTabAt(int index) 得到选项卡
  • getTabCount() 得到选项卡的总个数
  • getTabGravity() 得到 tab 的 Gravity
  • getTabMode() 得到 tab 的模式
  • getTabTextColors() 得到 tab 中文本的颜色
  • newTab() 新建个 tab
  • removeAllTabs() 移除所有的 tab
  • removeTab(TabLayout.Tab tab) 移除指定的 tab
  • removeTabAt(int position) 移除指定位置的 tab
  • setOnTabSelectedListener(TabLayout.OnTabSelectedListener onTabSelectedListener) 为每个 tab 增加选择监听器
  • setScrollPosition(int position, float positionOffset, boolean updateSelectedText) 设置滚动位置
  • setTabGravity(int gravity) 设置 Gravity
  • setTabMode(int mode) 设置 Mode
  • setTabTextColors(ColorStateList textColor) 设置 tab 中文本的颜色
  • setTabTextColors(int normalColor, int selectedColor) 设置 tab 中文本的颜色 默认 选中
  • setTabsFromPagerAdapter(PagerAdapter adapter) 设置 PagerAdapter
  • setupWithViewPager(ViewPager viewPager) 和 ViewPager 联动

嗯嗯,暂时写到这里吧!想要熟悉TabLayout的使用,多敲敲代码就知道了。本文只是一些基本的使用,写得也不是很好。如果想更加熟悉与了解TabLayout,请查看爱哥的博客http://blog.csdn.net/aigestudio/article/details/47155769!过完年要正式开工啦!ps:创业公司太苦逼了,容我哭会去…

Demo下载地址:http://download.csdn.net/detail/richardli1228/9435769

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值