介绍

几行代码实现Android选项卡界面,支持标准底部Tab自定义视图选项卡,头部文字选项卡。

底部自定义视图选项卡

先来看看实现下图中的效果我们代码应该怎么写?

实现上图效果只需以下代码:

public class TestBottomTabActivity extends TabActivity {

    @Override
    protected List<TabItemView> getTabViews() {
        List tabviews = new ArrayList();
        tabviews.add(new TabItemView(this,"1",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        tabviews.add(new TabItemView(this,"2",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        tabviews.add(new TabItemView(this,"3",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        tabviews.add(new TabItemView(this,"4",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        return tabviews;
    }

    @Override
    protected List<Fragment> getFragments() {
        List fragments = new ArrayList();
        fragments.add(BlankFragment.newInstance("1",null));
        fragments.add(BlankFragment.newInstance("2",null));
        fragments.add(BlankFragment.newInstance("3",null));
        fragments.add(BlankFragment.newInstance("4",null));
        return fragments;
    }

    @Override
    protected List<String> getTitles() {
        return null;
    }

    @Override
    protected TabType getTabType() {
        return TabType.BottomCustomViewTab;
    }
}

头部文字选项卡

先来看看实现下图中的效果我们代码应该怎么写?

实现上图效果只需以下代码:

public class TestTopTabActivity extends TabActivity {

    @Override
    protected List<TabItemView> getTabViews() {
        return null;
    }

    @Override
    protected List<Fragment> getFragments() {
        List fragments = new ArrayList();
        fragments.add(BlankFragment.newInstance("1",null));
        fragments.add(BlankFragment.newInstance("2",null));
        fragments.add(BlankFragment.newInstance("3",null));
        fragments.add(BlankFragment.newInstance("4",null));
        return fragments;
    }

    @Override
    protected List<String> getTitles() {
        List list = new ArrayList();
        list.add("待支付");
        list.add("待发货");
        list.add("待收货");
        list.add("待评价");
        return list;
    }

    @Override
    protected TabType getTabType() {
        return TabType.TopTitleTab;
    }
}

实现

准备知识

我们都知道在android.support.design.widget包中为我们提供了TabLayout用来进行水平方向的tab展示,不清楚的同学可以先百度了解一下,用法很简单,大致如下:

        viewPager = (ViewPager) findViewById(R.id.viewPager);
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);

         //为viewPager设置一个FragmentPagerAdapter
        pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this);
        viewPager.setAdapter(pagerAdapter);
        //进行关联
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_FIXED);

实现一个头部文字选项卡

为了能够快速实现一个头部文字选项卡,我们可以将一些不变的代码写在一个父类Activity,让后提供抽象方法来让子类去实现会变化的代码,由此如果我们实现一个头头部文字选项卡抽象类如下:

1、首先定义布局

activity_tab_top.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">
    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="48dp"></android.support.design.widget.TabLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#d3d3d3"
        android:orientation="vertical">
    </View>
    <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>
</LinearLayout>

2、抽象类实现

public abstract class TabActivity extends AppCompatActivity{

    private ViewPager viewPager;
    private TabLayout tabLayout;
    private SimpleFragmentPagerAdapter pagerAdapter;

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

    private void initView() {
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);

        pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this);
        viewPager.setAdapter(pagerAdapter);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_FIXED);
    }

    protected abstract List<Fragment> getFragments();//返回tab对应的fragment
    protected abstract List<String> getTitles();//头部显示的title列表

    public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {

        public SimpleFragmentPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
        }

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

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

        @Override
        public CharSequence getPageTitle(int position) {
            if (getTitles()!=null&&!getTitles().isEmpty()){
                return getTitles().get(position);
            }
            return null;
        }

    }
}

以上代码便实现了一个通用的头部文字选项卡抽象类,以后要实现类似上面图2界面只需要这样:

public class TestTopTabActivity extends TabActivity {

    @Override
    protected List<Fragment> getFragments() {
        List fragments = new ArrayList();
        fragments.add(BlankFragment.newInstance("1",null));
        fragments.add(BlankFragment.newInstance("2",null));
        fragments.add(BlankFragment.newInstance("3",null));
        fragments.add(BlankFragment.newInstance("4",null));
        return fragments;
    }

    @Override
    protected List<String> getTitles() {
        List list = new ArrayList();
        list.add("待支付");
        list.add("待发货");
        list.add("待收货");
        list.add("待评价");
        return list;
    }
}

实现一个底部自定义视图选项卡

要实现一个底部自定义视图要相对麻烦一点,因为底部的视图是由我们提供的,所以需要一个我们的自定义视图,那么怎么实现呢,我们可能想到在底部设置写一个自定义能添加底部视图的view,然后做不同的点击处理。但是TabLayout下的每个tab其实是支持设置自定义视图的,只需要调用TabLayout.Tab对象提供的setCustomView方法即可。

这样我们提供一个底部自定义视图选项卡的抽象类如下:

1、首先定义布局

activity_tab.xml

<?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">

    <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>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#d3d3d3"
        android:orientation="vertical">
    </View>
    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        app:tabIndicatorHeight="0dp"
        android:layout_height="48dp"></android.support.design.widget.TabLayout>
</LinearLayout>

2、抽象类实现

public abstract class TabActivity extends AppCompatActivity{

    private ViewPager viewPager;
    private TabLayout tabLayout;
    private SimpleFragmentPagerAdapter pagerAdapter;
    private TabType mTabType = TabType.BottomCustomViewTab;

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

    private void initView() {
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);

        pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this);
        viewPager.setAdapter(pagerAdapter);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_FIXED);

        if (getTabViews()!=null){
            for (int i = 0; i < tabLayout.getTabCount(); i++) {
                TabLayout.Tab tab = tabLayout.getTabAt(i);
                tab.setCustomView(pagerAdapter.getTabView(i));
            }
        }
    }

    protected abstract List<TabItemView> getTabViews();//返回底部自定义tab视图
    protected abstract List<Fragment> getFragments();//返回tab对应的fragment

    public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {

        public SimpleFragmentPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
        }

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

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

        public View getTabView(int position) {
            return getTabViews().get(position);
        }

    }}

上面代码和之前实现一个头部标题选项卡的抽象类大致一样,只是提供了 protected abstract List getTabViews()方法用于让子类提供底部自定义tab视图TabItemView,底部视图一般就是一个图片加一个文字,那么我们自定义一个底部视图TabItemView如下。

TabItemView实现如下:

public class TabItemView extends LinearLayout {

    /**
     * Item 的标题
     */
    public String title;

    public int textColor;
    public int iconDrawable;
    public int bgDrawable;

    public TextView tvTitle;
    public ImageView ivIcon;

    public TabItemView(Context context, String title, int textColor, int iconDrawable,
                       int bgDrawable) {
        super(context);
        this.title = title;
        this.iconDrawable = iconDrawable;
        this.textColor = textColor;
        this.bgDrawable = bgDrawable;
        init();
    }

    /**
     * 初始化
     */
    public void init(){
        View view = LayoutInflater.from(super.getContext()).inflate(R.layout.view_tab_item, this);
        tvTitle = (TextView) view.findViewById(R.id.tvTitle);
        ivIcon = (ImageView) view.findViewById(R.id.ivIcon);

        LinearLayout.LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        layoutParams.weight = 1;
        view.setLayoutParams(layoutParams);

        if (iconDrawable!=0){
            ivIcon.setImageResource(iconDrawable);
        }
        if (bgDrawable!=0) {
            this.setBackgroundResource(bgDrawable);
        }
        if (textColor!=0){
            tvTitle.setTextColor(textColor);
        }
        tvTitle.setText(title);

    }
}

TabItemView对应布局:

view_tab_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/viewTabView"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:background="?android:selectableItemBackground"
    android:gravity="center"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/ivIcon"
        android:layout_weight="1"
        android:src="@mipmap/ic_launcher"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/tvTitle"
        android:layout_weight="1"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="首页"/>

</LinearLayout>

很简单就是提供一个构造方法在初始化的时候设置图片、文字、文字颜色等信息。

那么到此,我们如果遇到如上图1要实现一个底部视图选项卡只需要这样:

public class TestBottomTabActivity extends TabActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected List<TabItemView> getTabViews() {
        List tabviews = new ArrayList();
        tabviews.add(new TabItemView(this,"1",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        tabviews.add(new TabItemView(this,"2",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        tabviews.add(new TabItemView(this,"3",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        tabviews.add(new TabItemView(this,"4",R.color.colorPrimary,R.mipmap.ic_launcher,0));
        return tabviews;
    }

    @Override
    protected List<Fragment> getFragments() {
        List fragments = new ArrayList();
        fragments.add(BlankFragment.newInstance("1",null));
        fragments.add(BlankFragment.newInstance("2",null));
        fragments.add(BlankFragment.newInstance("3",null));
        fragments.add(BlankFragment.newInstance("4",null));
        return fragments;
    }
}

二者结合

到此相信你们已经发现实现头部文字选项卡或者底部自定义视图选项卡这里都用了TabLayout+ViewPager的方式,那么我们来个结合。

提供一个枚举指定tab类型,根据tab类型进行数据的获取即可。

组合之后的抽象类如下:

public abstract class TabActivity extends AppCompatActivity{

    private ViewPager viewPager;
    private TabLayout tabLayout;
    private SimpleFragmentPagerAdapter pagerAdapter;
    private TabType mTabType = TabType.BottomCustomViewTab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTabType = getTabType()==null?TabType.BottomCustomViewTab:getTabType();
        if (mTabType==TabType.BottomCustomViewTab){
            setContentView(R.layout.activity_tab);
        }else{
            setContentView(R.layout.activity_tab_top);
        }
        initView();
    }

    private void initView() {
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);

        pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this);
        viewPager.setAdapter(pagerAdapter);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_FIXED);

        if (getTabViews()!=null){
            for (int i = 0; i < tabLayout.getTabCount(); i++) {
                TabLayout.Tab tab = tabLayout.getTabAt(i);
                tab.setCustomView(pagerAdapter.getTabView(i));
            }
        }
    }

    protected abstract List<TabItemView> getTabViews();//返回底部自定义tab视图
    protected abstract List<Fragment> getFragments();//返回tab对应的fragment
    protected abstract List<String> getTitles();//头部显示的title列表
    protected abstract TabType getTabType();//tab类型-分为底部tab和头部tab

    public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {

        public SimpleFragmentPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
        }

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

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

        @Override
        public CharSequence getPageTitle(int position) {
            if (getTitles()!=null&&!getTitles().isEmpty()){
                return getTitles().get(position);
            }
            return null;
        }

        public View getTabView(int position) {
            return getTabViews().get(position);
        }

    }

    public enum TabType{//Tab类型
        BottomCustomViewTab,//底部自定义tab
        TopTitleTab//头部标题tab
    }
}

这样就实现了统一,以后不管是底部还是头部,只需要继承TabActivity之后实现相应的抽象方法即可(参考文章开头)。

结束

源码下载请点击:http://download.csdn.net/detail/yissan/9861159

是不是节省了一点点时间啊。如果本文对你有一点点帮助请关注我或者为我点赞!不胜感激!

Android快速开发-选项卡的更多相关文章

  1. Android 快速开发系列 打造万能的ListView GridView 适配器

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...

  2. Android快速开发不可或缺的11个工具类

     Android快速开发不可或缺的11个工具类  :http://www.devst ore.cn/code/info/363.html

  3. Android快速开发不可或缺的11个工具类(下载)

    功能分类:工具     支持平台:Android     运行环境:Eclipse 开发语言:Java      开发工具:Eclipse         源码大小:11.45KB   下载地址:ht ...

  4. (转载)实例详解Android快速开发工具类总结

    实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...

  5. Android快速开发系列 10个常用工具类

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅 ...

  6. 【转】 Android快速开发系列 10个常用工具类 -- 不错

    原文网址:http://blog.csdn.net/lmj623565791/article/details/38965311 转载请标明出处:http://blog.csdn.net/lmj6235 ...

  7. (转载)Android快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup

    [置顶] [Android]快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup 标签: androidAdapter快速开发0耦合 2016-12-1 ...

  8. [ 转]Android快速开发–使用ORMLite操作数据库

    OrmLite是一个数据库操作辅助的开源框架,主要面向Java语言.在Android面向数据库开发中,是一个比较流行的开源框架,方便操作而且功能强大,今天来学习一下,最近的项目中也有所涉及,写个博客来 ...

  9. Android快速开发常用知识点系列目录

    项目构建 Android项目目录结构模板以及简单说明[简单版] Android Studio配置统一管理依赖版本号引用 Android多Module下的Application引用方式 APP开篇 An ...

随机推荐

  1. MySQL 数据类型(Day41)

    一.介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的高度,但宽度是可选的. mysql数据类型概览 #1.数字:(默认都是有符号,宽度指的是显示宽度,与存储无关) ...

  2. php优化,操作码优化,缓存优化

    一.php缓存加速器软件种类 xcache,eaccelerator,zend,apc如何选择:建议xcache,eaccelerator,二选一,首选xcachexcache更快 二.php缓存加速 ...

  3. git命令与协同开发

    一 git命令 1.简单命令 git init # 初始化 (建立git 版本相关文件关系都放这里) git config --global user.email "you@example. ...

  4. (转)牛B的代码不一定是好代码

    最近经常做业务逻辑代码review的工作,发现各种风格的代码,其中有一种是封装和抽象做的非常的多,代码层次非常的深入,表面给人感觉是:牛逼的代码. 但是从清晰度和可维护性来说,还是不推荐这么做. 1. ...

  5. LeetCode:路径总和II【113】

    LeetCode:路径总和II[113] 题目描述 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径. 说明: 叶子节点是指没有子节点的节点. 示例:给定如下二叉树, ...

  6. HackerRank - common-child【DP】

    HackerRank - common-child[DP] 题意 给出两串长度相等的字符串,找出他们的最长公共子序列e 思路 字符串版的LCS AC代码 #include <iostream&g ...

  7. Jsoup学习总结

    Jsoup学习总结 摘要 Jsoup是一款比较好的Java版HTML解析器.可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方 ...

  8. Linux常用命令(6/26)——dd命令和split命令

    dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 以可选块长度复制文件,默认情况下从标准输入设备输出到标准输出设备.复制过程中,还可以对文件进行一些转换. dd命令可以指定block的 ...

  9. error C2665: “std::locale::facet::operator new”: 2 个重载中没有一个可以转换所有参数类型

    qt项目 qt creator项目由插件自动转换成的vs2015项目,为了发布少带些dll ,切换成vs2013项目,在更改了一些vs2013不支持的c++新标准写法之后,release可正常编过,但 ...

  10. C++中 int main(int argc, char **argv) 命令行传递参数

    C++中,比较常见的是不带参数的主函数int main(),如果使用命令行执行程序,主函数也可以接收预先输入的参数,形式如下. int main(int argc,char **argv) argc: ...