Android TabLayout定制CustomView与ViewPager交互双向联动

我之前写了一些关于Android Material Design TabLayout的文章,
(1)《Android L、M扩展支持包design中widget:TabLayout》文章链接地址:http://blog.csdn.net/zhangphil/article/details/48859961
(2)《ViewPager与android.support.design.widget.TabLayout双向交互联动切换》文章链接地址:http://blog.csdn.net/zhangphil/article/details/48860469

如果设计的需求不要求选项卡在切换时附带有图标的切换效果、仅仅文字的颜色发生变化以响应用户的点击事件,那么以上两篇文章中介绍的内容足够满足一般常规开发(选项卡只有文字)需求。
但是,通常现在流行的app,底部的选项卡,不仅仅是简单的文字描述,往往还有图标,当用户在切换时候,图标也要发生状态变化(以示被选中),比如QQ、微信等这些常见的app底部选项栏。
TabLayout为解决这样的UI交互设计需求,开发者需要对TabLayout.Tab进行自定制view。
TabLayout中对TabLayout.Tab自定义选项Tab其实很简单,只需调用TabLayout.Tab的
tab.setCustomView(View view);
然后初始化完成ViewPager后,接着:
tabLayout.setupWithViewPager(viewPager);
按照道理来说即可完成TabLayout与ViewPager双向交互联动,就像我之前写的文章(2)中那样《ViewPager与android.support.design.widget.TabLayout双向交互联动切换》。
但是不巧的是,此处鱼与熊掌不可兼得,这么写代码只能适应文字的选项卡样式,如果在Tab中有自定义的view,那么一旦调用谷歌官方的Android SDK中的:
tabLayout.setupWithViewPager(viewPager);
意味着放弃自定义view,TabLayout内部在添加Tab时候,会自动从ViewPager适配器PagerAdapter的getPageTitle()获得一个字符串然后作为一个TextView添加到TabLayout中,换句话说,开发者自定义的view将被删掉然后完全失效。
对于这个问题,谷歌Android官方在此(https://code.google.com/p/android/issues/detail?id=180667 )给出了解释:


If you call setupWithViewPager() then you are telling it you use only the titles from the PagerAdapter.

Either call setupWithViewPager(), clear all the tabs and then add them again.

Or just do everything that the method does:

viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));

时间是:Jul 22, 2015

详情如图:

所以如果要实现自定义的view,那么就要放弃setupWithViewPager(),这样写代码才可以解决问题:
viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(tabLayout));
  tabLayout.setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));

现在给出一个改进后的代码例子。

测试用的主Activity MainActivity.java :

package zhangphil.view;import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.design.widget.TabLayout.Tab;
import android.support.design.widget.TabLayout.TabLayoutOnPageChangeListener;
import android.support.design.widget.TabLayout.ViewPagerOnTabSelectedListener;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;public class MainActivity extends Activity {private TabLayout tabLayout;private final int COUNT = 4;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tabLayout = (TabLayout) findViewById(R.id.tabLayout);tabLayout.setSmoothScrollingEnabled(true);tabLayout.setSelectedTabIndicatorHeight(10);MyViewPagerAdapter adapter = new MyViewPagerAdapter();LayoutInflater mLayoutInflater = this.getLayoutInflater();for (int i = 0; i < COUNT; i++) {Tab tab = tabLayout.newTab();View view = mLayoutInflater.inflate(R.layout.tab, null);tab.setCustomView(view);TextView text = (TextView) view.findViewById(R.id.textView);text.setText("选项卡" + i);tabLayout.addTab(tab);}ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);viewPager.setAdapter(adapter);viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(tabLayout));tabLayout.setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));// tabLayout.setupWithViewPager(viewPager);}private class MyViewPagerAdapter extends PagerAdapter {@Overridepublic Object instantiateItem(ViewGroup container, int pos) {TextView tv = new TextView(getApplicationContext());tv.setText("@ViewPager:" + pos);tv.setTextSize(30.0f);tv.setGravity(Gravity.CENTER);tv.setTextColor(Color.BLACK);container.addView(tv);return tv;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View) object);}@Overridepublic int getCount() {return COUNT;}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}}
}

MainActivity.java需要的布局文件activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><android.support.design.widget.TabLayoutandroid:id="@+id/tabLayout"android:layout_width="match_parent"android:layout_height="100dip"app:tabGravity="fill"app:tabIndicatorColor="#ff5252"app:tabMode="fixed" ></android.support.design.widget.TabLayout><android.support.v4.view.ViewPagerandroid:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

MainActivity.java中的TabLayout动态添加Tab需要的布局文件tab.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="vertical" ><ImageViewandroid:id="@+id/imageView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:src="@drawable/imageview_selector" /><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center"android:text="TextView"android:textColor="@drawable/textview_selector" /></LinearLayout>

tab.xml布局文件涉及到了两个位于drawable目录下的selector文件:textview_selector.xml和imageview_selector.xml。这两个selector代码文件目的是当某个选项卡被切换到的时候图标icon和文字颜色发生相应的变化。

textview_selector.xml代码文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_selected="true" android:color="#ff5252"></item>  <item android:state_selected="false" android:color="#26c6da"></item>
</selector>

imageview_selector.xml代码文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_selected="true" android:drawable="@drawable/emo_im_cool"></item>  <item android:state_selected="false" android:drawable="@drawable/ic_launcher"></item>
</selector>

其中一个Android系统自带的小图标emo_im_cool.png:

全部代码运行结果如图所示:

附参考文章:
《Android Material Design TabLayout属性app:tabMode和app: tabGravity》文章链接地址:http://blog.csdn.net/zhangphil/article/details/48931483

Android TabLayout定制CustomView与ViewPager交互双向联动相关推荐

  1. 011 Android TabLayout+ViewPager实现顶部滑动效果(多个页面)

    1.TabLayout介绍 TabLayout提供了一个水平的布局用来展示Tabs,很多应用都有这样的设计,典型的有网易新闻,简书,知乎等.TabLayout就可以很好的完成这一职责,首先TabLay ...

  2. Android TabLayout和ViewPager

    In this tutorial we'll be implementing a ViewPager under the TabLayout that we'd already implemented ...

  3. android 圆角边框边框渐变,Android深度定制化TabLayout:圆角,渐变色,背景边框,圆角渐变下划线,基于Android原生TabLayout...

    Android深度定制化TabLayout:圆角,渐变色,背景边框,圆角渐变下划线,基于Android原生TabLayout 在附录1的基础上丰富自定义的TabLayout,这次增加两个内容: 1,当 ...

  4. Android TabLayout(选项卡布局)简单用法实例分析

    本文实例讲述了Android TabLayout(选项卡布局)简单用法.分享给大家供大家参考,具体如下: 我们在应用viewpager的时候,经常会使用TabPageIndicator来与其配合.达到 ...

  5. Android --- TabLayout 切换时,改变选项卡下字体的状态(大小、加粗、默认被选中第一个)

    文章目录 一.前言 二.源码实例 1.选项卡所在的布局文件 `fragment_course_selection.xml` 2.选项卡所在类 `CourseSelectionFragment.java ...

  6. AppBarLayout中的Android TabLayout

    In this tutorial, we'll discuss and implement Android TabLayout in our android application. Also we' ...

  7. 国内支持原生android吗,定制安卓和原生Android到底有哪些不同之处?彻底真相了...

    相信大家都知道最近在搞机圈有个大新闻,就是小米即将于8月份推出MIUI 9.近日小米MIUI市场副总监@黄龙中 就在微博上征求米粉意见,暗示MIUI 9可能长下面这样. 小米最新官方主题<几何& ...

  8. 一加点击android系统时间,终于等到你!一加发布国内首个Android P定制系统 一加6抢先体验...

    原标题:终于等到你!一加发布国内首个Android P定制系统 一加6抢先体验 目前国产手机采用的都是安卓系统,由于某些不可抗力的因素,安卓原生系统在国内很多功能都无法正常使用,因此国产手机采用谷歌的 ...

  9. Android TabLayout总结

    文章目录 Android TabLayout总结 基本使用 添加图标.隐藏下划线 自定义下划线.添加分割线 设置角标 圆角样式 自定义View+Lottile 代码下载 Android TabLayo ...

最新文章

  1. 我的人生,需要一个计划
  2. 部署企业私有镜像仓库Harbor
  3. 【javascript 对日期的扩展 Format\addDays】
  4. mac安装和卸载mysql_基于centos7系统卸载rpm安装的mysql
  5. 如何有效解决C与C++的相互调用问题
  6. 关于内存条的知识要点⑴
  7. 【Scratch算法讲解】01-Scratch选择排序 少儿编程Scratch常见排序算法案例分析讲解
  8. 前端web设计师_Web设计师的时尚Web设计主题
  9. ThoughtWorks的敏捷测试
  10. 电子计算机 隐形眼镜,戴隐形眼镜看电脑要注意什么
  11. wuauclt.exe是什么进程?为什么运行?wuauclt.exe进程介绍
  12. 用高德地图罗永浩语音包 随时听老罗讲段子
  13. 2018妙计旅行笔试题
  14. 一起做网店的商品主图的批量采集的步骤
  15. java properties map_为什么java.util.Properties实现Map而不是Map
  16. Multimedia Event Extraction From News With a Unified Contrastive Learning Framework论文解读
  17. 20100919星期天最折腾的一天。
  18. 「水」滔天巨浪---牛客小白
  19. EA周报 | 字节跳动上线搜索引擎;电影《哪吒之魔童降世》累计综合票房破15亿;鸿蒙系统首发设备欲屏蔽开机广告...
  20. 【Ajax】简单入门 - 不深究

热门文章

  1. tomcat中间件的默认端口号_死磕Tomcat系列(1)——整体架构
  2. MockServer 服务框架设计
  3. matlab虚拟现实之工具介绍(修改)
  4. linux mysql utf-8编码_笔记:linux下mysql设置utf-8编码方法
  5. c语言找最长串指针改错,2013年计算机二级C语言上机试题及解析35
  6. unique Signatures of Histograms for local surface description
  7. 朴素贝叶斯算法+模型的评价-查准率、召回率、F1-score及混淆矩阵(code实现)
  8. eja智能压力变送器工作原理_电量变送器是什么?电量变送器工作原理解析
  9. 计算机视觉(二)——深度学习进阶
  10. 干货!全网最全一套目标检测、卷积神经网络和OpenCV学习资料(教程/PPT/代码)...