TabLayout+Viewpager+Fragment,在tab中显示一个红点,用来标识是否有新消息未读,需要实时刷新。又或者tab中显示的内容需要自定义,不止显示文字,文字还需要不同的背景变换。
直接父类是 HorizontalScrollView 横向滑动的ScrollView
最重要的使用方法:setupWithViewPager (ViewPager viewPager)
咱依次来看(其实看属性名,大概就知道这是干啥使的),当然TabLayout不光有这些属性,它父类有的它都可以使用。
android.support.design:tabBackground — 设置的背景。
android.support.design:tabContentStart — 相对起始位置tab的Y轴偏移量。
android.support.design:tabGravity — tab的布局方式,两个值GRAVITY_CENTER (内容中心显示) 和 GRAVITY_FILL (内容尽可能充满TabLayout)。
android.support.design:tabIndicatorColor — 设置tab指示器(tab的下划线)的颜色。
android.support.design:tabIndicatorHeight — 设置tab指示器(tab的下划线)的高度。
android.support.design:tabMaxWidth — 设置tab选项卡的最大宽度。
android.support.design:tabMinWidth — 设置tab选项卡的最小宽度。
android.support.design:tabMode — 设置布局中tab选项卡的行为模式,两个常量MODE_FIXED (固定的tab)和 MODE_SCROLLABLE(滑动的tab)。
android.support.design:tabPadding — 设置tab的内边距(上下左右)。
android.support.design:tabPaddingBottom — 设置tab的底部内边距。
android.support.design:tabPaddingEnd — 设置tab的右侧内边距。
android.support.design:tabPaddingStart — 设置tab的左侧内边距。
android.support.design:tabPaddingTop — 设置tab的上方内边距。
android.support.design:tabSelectedTextColor — 设置tab被选中时的文本颜色。
android.support.design:tabTextColor — 设置tab默认的文本颜色。
android.support.design:tabTextAppearance — 设置tab的TextAppearance样式的引用,可以引用另一个资源,形式为“@ [+] [package:] type / name”或主题属性,格式为“?[package:] type / name”。。
addOnTabSelectedListener(TabLayout.OnTabSelectedListener listener)
添加一个TabLayout.OnTabSelectedListener监听事件,当tab选择更改时,它将被调用。
addTab(TabLayout.Tab tab,boolean setSelected)
向此布局添加选项卡。
addTab(TabLayout.Tab tab,int position)
向此布局添加选项卡。
addTab(TabLayout.Tab tab)
向此布局添加选项卡。
addTab(TabLayout.Tab tab,int position,boolean setSelected)
向此布局添加选项卡。
addView(View child,int index)
添加子视图到指定位置。
addView(View child)
添加子视图。
addView(View child,ViewGroup.LayoutParams params)
添加具有指定布局参数的子视图。
addView(View child,int index,ViewGroup.LayoutParams params)
添加具有指定布局参数的子视图。
clearOnTabSelectedListeners()
删除所有以前添加的TabLayout.OnTabSelectedListeners。
FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs)
根据提供的属性集返回一组新的布局参数。
int getSelectedTabPosition()
返回当前所选标签的位置。
TabLayout.Tab getTabAt(int index)
返回指定位置的tab。
int getTabCount()
返回当前在操作栏中注册的选项卡数。
int getTabGravity()
返回当前的标签tab的布局方式,GRAVITY_CENTER (内容中心显示) 和 GRAVITY_FILL (内容尽可能充满TabLayout)。
int getTabMode()
返回tab选项卡的行为模式,MODE_FIXED* (固定的tab)和 MODE_SCROLLABLE(滑动的tab)。
ColorStateList getTabTextColors()
获取用于选项卡的不同状态(正常,已选择)的文本颜色。
TabLayout.Tab newTab ()
创建并返回一个新的TabLayout.Tab。
removeAllTabs()
从操作栏中删除所有选项卡,并取消选择当前选项卡。
removeOnTabSelectedListener(TabLayout.OnTabSelectedListener listener)
删除以前通过addOnTabSelectedListener(OnTabSelectedListener)添加的给定
TabLayout.OnTabSelectedListener,tab选中监听器。
removeTab(TabLayout.Tab tab)
从布局中删除选项卡。
removeTabAt(int position)
从布局中删除选项卡。
setOnTabSelectedListener(TabLayout.OnTabSelectedListener listener)
API方法24.0.0中已弃用此方法。使用addOnTabSelectedListener(OnTabSelectedListener)和removeOnTabSelectedListener(OnTabSelectedListener)。
setScrollPosition(int position,float positionOffset,boolean updateSelectedText)
设置选项卡的滚动位置,当标签tab显示为滚动容器(如ViewPager)的一部分时,此功能非常有用。
参数:
位置int:当前滚动位置
positionOffset float:表示从位置偏移的[0, 1)的值。
updateSelectedText boolean:是否更新文本的选择状态。。
setSelectedTabIndicatorColor(int color)
设置选中的tab的指示器(下划线)颜色。
setSelectedTabIndicatorHeight(int height)
设置选中的tab的指示器的高度。
setTabGravity(int gravity)
设置TabLayout的布局方式,GRAVITY_CENTER (内容中心显示) 和 GRAVITY_FILL (内容尽可能充满TabLayout)。。
setTabMode(int mode)
设置tab选项卡的行为模式,MODE_FIXED* (固定的tab)和 MODE_SCROLLABLE(滑动的tab)。
setTabTextColors(int normalColor,int selectedColor)
设置用于选项卡的不同状态(常规,选定)的文本颜色。
setTabTextColors(ColorStateList textColor)
设置用于选项卡的不同状态(常规,选定)的文本颜色。
setTabsFromPagerAdapter(PagerAdapter adapter)
API方法23.2.0中已弃用此方法。使用setupWithViewPager(ViewPager)将TabLayout与ViewPager链接在一起。当使用该方法时,当更改PagerAdapter时,TabLayout将自动更新。
setupWithViewPager(ViewPager viewPager,boolean autoRefresh)
将TabLayout与ViewPager链接在一起,当更改PagerAdapter时,TabLayout是否更新由autoRefresh决定。
setupWithViewPager(ViewPager viewPager)
将TabLayout与ViewPager链接在一起。
shouldDelayChildPressedState()
如果此ViewGroup的子代或子孙后代按下的状态应该被延迟,则返回true。 一般来说,应该对可以滚动的容器(如List)进行此操作。 这防止当用户实际上尝试滚动内容时出现按压状态。 由于兼容性原因,默认实现返回true。 不滚动的子类通常会覆盖此方法并返回false。
列举几种在项目中用的实例
要点:自定义TabLayout中的tab
3.1.1 、 TabLayout中的tab布局文件
3.1.2 、 tab中的选择器
3.1.3 、 viewpager适配器MyFragmentPagerAdapter
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private Context context;
private String[] mTitles = new String[]{"首页", "分类", "积分商城","外卖","购物车"};
public MyFragmentPagerAdapter(FragmentManager fm , Context context) {
super(fm);
this.context = context;
}
private ShopcarFragment carFragment;
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return HomeFragment.newInstance();
case 1:
return TypeFragment.newInstance();
case 2:
return ScoreMallFragment.newInstance();
case 3:
return TakeoutFragment.newInstance();
case 4:
if (carFragment == null){
carFragment =ShopcarFragment.newInstance();
}
return carFragment;
default:
return HomeFragment.newInstance();
}
}
@Override
public int getItemPosition(Object object) {
if (object instanceof ScoreMallFragment){
return POSITION_NONE; // 刷新
}
return POSITION_UNCHANGED;
}
@Override
public int getCount() {
return mTitles.length;
}
//ViewPager与TabLayout绑定后,这里获取到PageTitle就是Tab的Text
@Override
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
private int[] imageResId = {R.drawable.selecter_home_tab, R.drawable.selecter_mall_tab, R.drawable.selecter_score_tab, R.drawable
.selecter_takeout_tab,R.drawable.selecter_car_tab};
public View getTabView(int position) {
View v = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) v.findViewById(R.id.textView);
tv.setText(mTitles[position]);
ImageView img = (ImageView) v.findViewById(R.id.imgView);
img.setImageResource(imageResId[position]);
return v;
}
}
3.1.4 、 MainActivtiy中使用
private void initView() {
mViewPager = (ViewPager) findViewById(R.id.main_viewPager);
mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), MainActivity.this);
mViewPager.setAdapter(myFragmentPagerAdapter);
//将TabLayout与ViewPager绑定在一起
mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
TabLayout.Tab tab = mTabLayout.getTabAt(i);
//设置要用于对应tab的自定义视图。
if (tab != null) {
tab.setCustomView(myFragmentPagerAdapter.getTabView(i));
}
//----------------1010zuo----跳到指定的fragment--------------------------
if (isScore&&2 == i){
mViewPager.setCurrentItem(i);
}
if (isCar&&4 == i){
mViewPager.setCurrentItem(i);
}
//----------------1010zuo------------------------------
}
if (!isScore&&!isCar) {
mViewPager.setCurrentItem(1);
mViewPager.setCurrentItem(0);
}
...
}
重点:获取自定义tab中的控件,进行相关操作
3.2.1 、 TabLayout中的tab布局文件
3.2.2 、 tab中的文本选择器
3.2.3 、 viewpager适配器MyMsgAdapter
public class MyMsgAdapter extends FragmentPagerAdapter {
private Context context;
private Handler tabHandler;
private String[] mTitles = new String[]{"交易消息", "系统消息"};
public MyMsgAdapter(FragmentManager fm, Context context,Handler handler) {
super(fm);
this.context = context;
this.tabHandler = handler;
}
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return MsgBuyFragment.newInstance(tabHandler);
case 1:
return MsgSystemFragment.newInstance(tabHandler);
default:
return MsgBuyFragment.newInstance(tabHandler);
}
}
@Override
public int getCount() {
return mTitles.length;
}
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
public View getTabView(int position) {
View v = LayoutInflater.from(context).inflate(R.layout.msg_tab, null);
TextView tv = (TextView) v.findViewById(R.id.textView);
tv.setText(mTitles[position]);
return v;
}
}
3.2.4 、MyMsgActivity中使用
重点是刷新消息的时候,获取自定义tab中的相关控件。最主要的就是tab的两个方法,setCustomView()和getCustomView(),设置tab的自定义布局和获取tab的自定义布局
private void initView() {
//使用适配器将ViewPager与Fragment绑定在一起
adapter = new MyMsgAdapter(getSupportFragmentManager(), MyMsgActivity.this,tabHandler);
viewPagerMsg.setAdapter(adapter);
//将TabLayout与ViewPager绑定在一起
tablayoutMsg.setupWithViewPager(viewPagerMsg);
for (int i = 0; i < tablayoutMsg.getTabCount(); i++) {
TabLayout.Tab tab = tablayoutMsg.getTabAt(i);
if (tab != null) {
tab.setCustomView(adapter.getTabView(i));
}
}
}
private int notReadSys = 0;
private int notReadBuy = 0;
private Handler tabHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case mConstants.REFRESH_MSG_TAB:
int msgNum = (int) msg.getData().get("msgNum");
String msgType = (String) msg.getData().get(mConstants.TYPE_MSG);
if (mConstants.SYS_MSG.equals(msgType)){
notReadSys = msgNum ;
}else if (mConstants.BUY_MSG.equals(msgType)){
notReadBuy = msgNum ;
}
updateUnreadLabel();
break;
default:
break;
}
}
};
/**
* 刷新未读消息数
*/
public void updateUnreadLabel() {
for (int i = 0; i < tablayoutMsg.getTabCount(); i++) {
TabLayout.Tab tab = tablayoutMsg.getTabAt(i);
TextView hasNewMsg = (TextView)tab.getCustomView().findViewById(R.id.has_new_msg);
hasNewMsg.setVisibility(View.INVISIBLE);
if (0==i){
if (notReadBuy>0){
hasNewMsg.setVisibility(View.VISIBLE);
}
}
if (1==i){
if (notReadSys>0){
hasNewMsg.setVisibility(View.VISIBLE);
}
}
}
}
这里的方法,就不做中文说明了,看方法名就知道了,而且上面已经讲到了setCustomView()和getCustomView()两个方法。