Android快速开发-选项卡
介绍
几行代码实现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快速开发-选项卡的更多相关文章
- Android 快速开发系列 打造万能的ListView GridView 适配器
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...
- Android快速开发不可或缺的11个工具类
Android快速开发不可或缺的11个工具类 :http://www.devst ore.cn/code/info/363.html
- Android快速开发不可或缺的11个工具类(下载)
功能分类:工具 支持平台:Android 运行环境:Eclipse 开发语言:Java 开发工具:Eclipse 源码大小:11.45KB 下载地址:ht ...
- (转载)实例详解Android快速开发工具类总结
实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...
- Android快速开发系列 10个常用工具类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅 ...
- 【转】 Android快速开发系列 10个常用工具类 -- 不错
原文网址:http://blog.csdn.net/lmj623565791/article/details/38965311 转载请标明出处:http://blog.csdn.net/lmj6235 ...
- (转载)Android快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup
[置顶] [Android]快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup 标签: androidAdapter快速开发0耦合 2016-12-1 ...
- [ 转]Android快速开发–使用ORMLite操作数据库
OrmLite是一个数据库操作辅助的开源框架,主要面向Java语言.在Android面向数据库开发中,是一个比较流行的开源框架,方便操作而且功能强大,今天来学习一下,最近的项目中也有所涉及,写个博客来 ...
- Android快速开发常用知识点系列目录
项目构建 Android项目目录结构模板以及简单说明[简单版] Android Studio配置统一管理依赖版本号引用 Android多Module下的Application引用方式 APP开篇 An ...
随机推荐
- javascript 中的比较大小,兼 typeof()用法
javascript中的排序: 1.不同类型 比 类型 (字符串 > 数字) 2.同类型:(字符串 比 按字母顺序 )(数字 比 大小) 测试: <!DOCTYPE html> ...
- hadoop27---netty中handler的执行顺序
Netty是基于Java NIO的网络应用框架. Netty是一个NIO client-server(客户端服务器)框架,使用Netty可以快速开发网络应用,例如服务器和客户端协议.Netty提供了一 ...
- LVS原理详解以及部署
linux virtual server简称LVS,Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲, CPU. ...
- Windows 下c获取文件目录
由于要插数据库,构建sql语句,需要文件名,在网上找了半天,无奈都是Linux下的专用函数,伤心,,还有那个下载URL ,还木搞好,就要走啦,心焦哇 #include<iostream> ...
- resin启动不成功
resin启动只有一个进程,但显示启动正常: Resin/4.0.35 launching watchdog at 127.0.0.1:28084Resin/4.0.35 started -serve ...
- java鲁棒性(健壮性)
java能检测编译和运行时的错误 java自己操作内存减少了内存出错的可能 java实现了真数组,避免了覆盖数据的可能 Java不支持指针操作,大大减少了错误发生的可能性 ... 备注: Java能运 ...
- Madplay移植到mini2440开发板【转】
本文转载自:https://blog.csdn.net/simanstar/article/details/24035379 madplay交叉编译 交叉编译器:arm-linux-gcc 3.4.1 ...
- cocoa应用程序中NSStatusItem的使用
mac上的应用程序除了左上方会有菜单之外,在屏幕的右上方也会有一个图标样的菜单,这个类似于windows上右下角的system tray. 本文讲述如何给自己的应用程序添加一个system tray( ...
- session的活化与钝化 (转)
session的活化与钝化就是当用户访问时网站异常,不能丢掉session,所有也必须采用文件存储:和之前那个统计网站访问量一样的原理. class Person implements必须实现这两个接 ...
- 关于jquery的each遍历,return只终止当前循环,不好使的解决办法
很奇怪,一般来说return会终止js,但是今天万万没想到的是,jquery 的each循环中,return不好使,做一记录, var result = true; $('input[type=&qu ...