自定义TabBarView,快速实现Tab+ViewPager的Activity
来源:互联网 发布:cost of equity 知乎 编辑:程序博客网 时间:2024/06/07 04:05
先来看两个Activity的页面效果:
这两个Activity页面的实现代码分别为:
HomeWithTabActivity.java
package zou.zohar.tabbarview.activity;import android.os.Bundle;import android.support.design.widget.Snackbar;import android.support.v4.app.Fragment;import android.view.View;import android.widget.ImageView;import java.util.ArrayList;import java.util.List;import zou.zohar.tabbarview.R;import zou.zohar.tabbarview.fragment.TabFragment1;import zou.zohar.tabbarview.fragment.TabFragment2;import zou.zohar.tabbarview.fragment.TabFragment3;import zou.zohar.tabbarview.fragment.TabFragment4;import zou.zohar.tabbarview.widge.TabBarView;public class HomeWithTabActivity extends TabWithViewPagerBaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public TabBarView.ItemStyle getItemStyle() { return TabBarView.ItemStyle.ICON_TEXT; } @Override public List<TabBarView.TabItemView> getTabViews() { List<TabBarView.TabItemView> tabItemViews = new ArrayList<>(); tabItemViews.add(new TabBarView.TabItemView(this, "标题1", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); tabItemViews.add(new TabBarView.TabItemView(this, "标题2", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); tabItemViews.add(new TabBarView.TabItemView(this, "标题3", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); tabItemViews.add(new TabBarView.TabItemView(this, "标题4", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); return tabItemViews; } @Override public List<Fragment> getFragments() { List<Fragment> fragments = new ArrayList<>(); fragments.add(new TabFragment1()); fragments.add(new TabFragment2()); fragments.add(new TabFragment3()); fragments.add(new TabFragment4()); return fragments; } @Override public View getCenterView() { ImageView imageView = new ImageView(this); imageView.setImageResource(R.mipmap.ic_launcher_round); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Snackbar.make(v, "center view click", Snackbar.LENGTH_SHORT).show(); } }); return imageView; } @Override public int getContentLayout() { return R.layout.activity_home_with_tab; }}
OrderListWithTabActivity.java
package zou.zohar.tabbarview.activity;import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.View;import java.util.ArrayList;import java.util.List;import zou.zohar.tabbarview.R;import zou.zohar.tabbarview.fragment.TabFragment1;import zou.zohar.tabbarview.fragment.TabFragment2;import zou.zohar.tabbarview.fragment.TabFragment3;import zou.zohar.tabbarview.fragment.TabFragment4;import zou.zohar.tabbarview.widge.TabBarView;public class OrderListWithTabActivity extends TabWithViewPagerBaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public TabBarView.ItemStyle getItemStyle() { return TabBarView.ItemStyle.TEXT; } @Override public List<TabBarView.TabItemView> getTabViews() { List<TabBarView.TabItemView> tabItemViews = new ArrayList<>(); tabItemViews.add(new TabBarView.TabItemView(this, "已完成", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); tabItemViews.add(new TabBarView.TabItemView(this, "未付款", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); tabItemViews.add(new TabBarView.TabItemView(this, "待收货", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); tabItemViews.add(new TabBarView.TabItemView(this, "待评价", R.color.colorPrimary, R.color.colorAccent, R.mipmap.ic_launcher, R.mipmap.ic_launcher_deep)); return tabItemViews; } @Override public List<Fragment> getFragments() { List<Fragment> fragments = new ArrayList<>(); fragments.add(new TabFragment1()); fragments.add(new TabFragment2()); fragments.add(new TabFragment3()); fragments.add(new TabFragment4()); return fragments; } @Override public View getCenterView() { return null; } @Override public int getContentLayout() { return R.layout.activity_order_list_with_tab; }}
看起来,两者的代码几乎是一模一样的,唯一不同的就是他们各自的xmlLayout布局文件不同。
接下来我们来看看具体是怎么实现的。
首先介绍一下我们的自定义标签栏
TabBarView.java
package zou.zohar.tabbarview.widge;import android.content.Context;import android.content.res.TypedArray;import android.support.annotation.NonNull;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import java.util.ArrayList;import java.util.List;import zou.zohar.tabbarview.R;public class TabBarView extends LinearLayout { /** * attribute * centerView的bottomMargin */ private int childrenBottomMargin; /** * tabItemView的展示样式 * 默认为 ICON_TEXT */ private ItemStyle mItemStyle = ItemStyle.ICON_TEXT; /** * 最新选择的item的position,-1表示没有选择任何一个 */ private int mCheckedPos = -1; /** * tabItemViews集合 */ private List<TabItemView> mTabItemViewList; public TabBarView(Context context) { super(context); init(); } public TabBarView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.TabItemView); childrenBottomMargin = attributes.getInt(R.styleable.TabItemView_childrenBottomMargin, 40); attributes.recycle(); init(); } private void init() { mTabItemViewList = new ArrayList<>(); } public void setItemStyle(@NonNull ItemStyle itemStyle) { this.mItemStyle = itemStyle; } public void setTabItemViews(@NonNull List<TabItemView> tabItemViews) { setTabItemViews(tabItemViews, null); } public void setTabItemViews(@NonNull List<TabItemView> tabItemViewList, View centerView) { /** * 不能重复设置mTabItemViewList */ if (mTabItemViewList.size() != 0) { throw new RuntimeException("mTabItemViewList cannot be repeated!"); } mTabItemViewList.addAll(tabItemViewList); if (mTabItemViewList.size() < 2) { throw new RuntimeException("The length of mTabItemViewList must not be less than 2!"); } for (int i = 0; i < mTabItemViewList.size(); i++) { if (centerView != null && i == mTabItemViewList.size() / 2) { /** * 给centerView设置childrenBottomMargin属性 */ LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.height = this.getLayoutParams().height + childrenBottomMargin; layoutParams.bottomMargin = childrenBottomMargin; layoutParams.gravity = Gravity.BOTTOM; centerView.setLayoutParams(layoutParams); this.addView(centerView); } final TabItemView tabItemView = mTabItemViewList.get(i); tabItemView.setItemStyle(mItemStyle == ItemStyle.ICON || mItemStyle == ItemStyle.ICON_TEXT, mItemStyle == ItemStyle.TEXT || mItemStyle == ItemStyle.ICON_TEXT); this.addView(tabItemView); final int currentItemPos = i; tabItemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (currentItemPos == mCheckedPos) { return; } check(currentItemPos); } }); } /** * 舒适化所有的tabItemView */ for (TabItemView tab : mTabItemViewList) { tab.setStatus(TabItemView.STATE_DEFAULT); } /** * 默认选中第一个 */ check(0); } /** * 通过position的选择设置tabItemView的标识,使用-1作为清除标识的选择 * * @param position tabItemView在TabBarView中的序号 */ public void check(int position) { if (position != -1 && position == mCheckedPos) { return; } if (mCheckedPos != -1) { mTabItemViewList.get(mCheckedPos).setStatus(TabItemView.STATE_DEFAULT); } if (position != -1) { mTabItemViewList.get(position).setStatus(TabItemView.STATE_CHECKED); } setCheckedPos(position); } private void setCheckedPos(int checkedPos) { mCheckedPos = checkedPos; if (mOnCheckedChangeListener != null) { mOnCheckedChangeListener.onCheckedChanged(this, mCheckedPos); } } public TabItemView getCheckedTabItemView() { return mTabItemViewList.get(mCheckedPos); } private OnCheckedChangeListener mOnCheckedChangeListener; /** * 注册一个回调函数,用来检查选项卡的选项更改 * * @param listener the callback to call on checked state change */ public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { mOnCheckedChangeListener = listener; } public interface OnCheckedChangeListener { /** * <p>Called when the checked tab item has changed. When the * selection is cleared, checkedId is -1.</p> * * @param tabBarView the tabBarView in which the checked tab item has changed * @param checkedPos the position of the newly checked tab item */ void onCheckedChanged(TabBarView tabBarView, int checkedPos); } public enum ItemStyle { ICON, TEXT, ICON_TEXT } /** * ItemView */ public static class TabItemView extends LinearLayout { /** * 状态: checked and default */ public final static int STATE_DEFAULT = 1; public final static int STATE_CHECKED = 2; /** * 标题:tabItemView上显示的文字 */ public String title; /** * 标题的颜色: checked and default */ public int colorDef; public int colorChecked; /** * 图标: checked and default */ public int iconResDef; public int iconResChecked; public ImageView ivIcon; public TextView tvTitle; public TabItemView(Context context, String title, int colorDef, int colorChecked, int iconResDef, int iconResChecked) { super(context); this.title = title; this.colorDef = colorDef; this.colorChecked = colorChecked; this.iconResDef = iconResDef; this.iconResChecked = iconResChecked; init(); } public void init() { View view = LayoutInflater.from(super.getContext()).inflate(R.layout.view_tab_item, this); ivIcon = (ImageView) view.findViewById(R.id.ivIcon); tvTitle = (TextView) view.findViewById(R.id.tvTitle); LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); layoutParams.weight = 1; view.setLayoutParams(layoutParams); tvTitle.setText(title); } protected void setItemStyle(boolean showIcon, boolean showTitle) { ivIcon.setVisibility(showIcon ? VISIBLE : GONE); tvTitle.setVisibility(showTitle ? VISIBLE : GONE); } /** * 设置itemView的状态 */ public void setStatus(int status) { ivIcon.setImageResource(status == STATE_CHECKED ? iconResChecked : iconResDef); tvTitle.setTextColor(ContextCompat.getColor(super.getContext(), status == STATE_CHECKED ? colorChecked : colorDef)); } }}
再来看看它的API:
public class TabBarView extends LinearLayout
TabBarView.ItemStyle
Item的展示样式枚举,有三种样式:ICON, TEXT, ICON_TEXT interface
TabBarView.OnCheckedChangeListener
点击Item切换tab时的回调 class TabBarView.TabItemView
ItemView,继承至LinearLayout
eg.childrenBottomMargin="40"
setItemStyle(@NonNull ItemStyle itemStyle)
设置tabItemView的展示样式 void
setTabItemViews(@NonNull List<TabItemView> tabItemViews)
设置tabItemView集合 void
setTabItemViews(@NonNull List<TabItemView> tabItemViewList, View centerView)
设置tabItemView集合和centerView void
void check(int position)
切换选中的tabItemView TabItemView
getCheckedTabItemView()
返回当前选中的tabItemView void
setOnCheckedChangeListener(OnCheckedChangeListener listener)
设置切换tabItemView时的回调接口
注意事项:
1. setTabItemViews() 方法不可重复调用。
2. 如果需要有一个子超出父布局位置限制的centerView的话,需要在TabBarView的父布局xml中添加属性 android:clipChildren=”false”。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_home_with_tab" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false"> <zou.zohar.tabbarview.widge.TabBarView android:id="@+id/tabBarView" android:layout_width="match_parent" android:layout_height="46dp" tools:childrenBottomMargin="40" /></RelativeLayout>
接下来,看一看用TabBarView+ViewPager封装的一个抽象的Activity
TabWithViewPagerBaseActivity.java
package zou.zohar.tabbarview.activity;import android.os.Bundle;import android.support.annotation.LayoutRes;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.view.View;import java.util.List;import zou.zohar.tabbarview.R;import zou.zohar.tabbarview.widge.TabBarView;/** * Created by zohar on 2017/5/21. * 抽象的含TabBarView和ViewPager的Activity */public abstract class TabWithViewPagerBaseActivity extends AppCompatActivity { private TabBarView tabBarView; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentLayout()); tabBarView = (TabBarView) findViewById(R.id.tabBarView); viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { return getFragments().get(position); } @Override public int getCount() { return getFragments().size(); } }); tabBarView.setItemStyle(getItemStyle() != null ? getItemStyle() : TabBarView.ItemStyle.ICON_TEXT); tabBarView.setTabItemViews(getTabViews(), getCenterView()); tabBarView.setOnCheckedChangeListener(new TabBarView.OnCheckedChangeListener() { @Override public void onCheckedChanged(TabBarView tabBarView, int checkedPos) { viewPager.setCurrentItem(checkedPos); } }); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { tabBarView.check(position); } @Override public void onPageScrollStateChanged(int state) { } }); } /** * @return 返回tabItemView的展示样式 ( ICON, TEXT, ICON_TEXT) */ public abstract TabBarView.ItemStyle getItemStyle(); public abstract List<TabBarView.TabItemView> getTabViews(); public abstract List<Fragment> getFragments(); public abstract View getCenterView(); /** * @return 返回xml布局文件 */ public abstract @LayoutRes int getContentLayout();}
看看它的API:
public abstract class TabWithViewPagerBaseActivity extends AppCompatActivity
getItemStyle()
返回tabItemView的展示样式 List
getTabViews()
提供tabItemView的集合,不可返回null List< Fragment>
getFragments()
提供Fragment的集合,不可返回null View
getCenterView()
提供一个中间按钮,可返回null int
getContentLayout()
提供xml布局文件
注意事项:
1. 你的Activity的onCreat()方法中不能调用setContentView(int resLayout)方法,xmlLayout必须由getContentLayout()方法提供。
2. 由getContentLayout()方法提供的xml布局文件中必须得至少包含一个id为R.id.tabBarView的TabBarView和一个id为R.id.viewpager的ViewPager。
3. getTabViews()和getFragments()分别提供的集合的长度必须一致。
- 自定义TabBarView,快速实现Tab+ViewPager的Activity
- Tab+ViewPager的实现
- 自定义tabbarView
- 快速实现自定义Tab复用
- Android--自定义tab+viewPager
- 自定义Tab + ViewPager控件
- 自定义的带tab的可左右滑动的viewpager之一 简单实现
- Viewpager和fragment和自定义的底部Tab实现切换效果
- [转]用Fragment+ViewPager+Tab实现快速导航
- viewpager+frament实现简单的tab
- 实现ViewPager与Tab之间的交互
- viewpager+tab 主界面的实现
- 自定义tab,viewpager实现仿tablayout切换效果
- ViewPager实现Tab布局
- viewpager实现Tab
- ViewPager实现tab
- ViewPager实现Tab
- ViewPager实现Tab
- [RK3288][Android6.0] Audio的DMA调用实例流程
- Spring MVC 整合irpeort(JasperReport) 5.6 开发及问题总结
- TensorFlow神经网络优化策略
- 攻击方式学习之(4)
- Codeforces Round #414 (Div1+Div2) G Replace All (组合数学)
- 自定义TabBarView,快速实现Tab+ViewPager的Activity
- centos7 安装shadowsocks客户端
- HTML
- centos6 安装 xgboost0.6
- 禁止cookie如何获得session的值
- 如何在windows7下建立Pixhawk的Eclipse编译开发环境
- Activity给自己下面其中一个Fragment传数据
- Linux脚本调用Java模板,将Properties文件放到CLASSPATH中的配置方式
- 初识jemeter和第一个例子