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

简介: Android TabLayout定制CustomView与ViewPager交互双向联动我之前写了一些关于Android Material Design TabLayout的文章,(1)《Android L、M扩展支持包design中widget:TabLayout》文章链接地址:http://blog.


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;

	@Override
	protected 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 {

		@Override
		public 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;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			container.removeView((View) object);
		}

		@Override
		public int getCount() {
			return COUNT;
		}

		@Override
		public 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.TabLayout
        android: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.ViewPager
        android: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" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/imageview_selector" />

    <TextView
        android: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


相关文章
|
8月前
|
Android开发
android 快速更改TabLayout的选中背景颜色。
android 快速更改TabLayout的选中背景颜色。
124 0
|
3月前
|
Java Linux Android开发
移动应用开发与操作系统的交互:深入理解Android和iOS
在数字时代,移动应用成为我们日常生活的一部分。本文将深入探讨移动应用开发的核心概念、移动操作系统的工作原理以及它们如何相互作用。我们将通过实际代码示例,展示如何在Android和iOS平台上创建一个简单的“Hello World”应用,并解释其背后的技术原理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和知识。
|
7月前
|
Android开发 容器
35. 【Android教程】视频页面:ViewPager
35. 【Android教程】视频页面:ViewPager
66 3
|
8月前
|
JSON Android开发 数据格式
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
97 2
|
5月前
|
XML Android开发 UED
"掌握安卓开发新境界:深度解析AndroidManifest.xml中的Intent-filter配置,让你的App轻松响应scheme_url,开启无限交互可能!"
【8月更文挑战第2天】在安卓开发中,scheme_url 通过在`AndroidManifest.xml`中配置`Intent-filter`,使应用能响应特定URL启动或执行操作。基本配置下,应用可通过定义特定URL模式的`Intent-filter`响应相应链接。
128 12
|
5月前
|
Android开发
Android使用ViewPager做无限轮播,人为滑动时停止
Android使用ViewPager做无限轮播,人为滑动时停止
98 2
|
5月前
|
JSON Android开发 数据格式
Android项目架构设计问题之实现交互响应的结构化处理如何解决
Android项目架构设计问题之实现交互响应的结构化处理如何解决
22 0
|
7月前
|
JavaScript 前端开发 Android开发
kotlin安卓在Jetpack Compose 框架下使用webview , 网页中的JavaScript代码如何与native交互
在Jetpack Compose中使用Kotlin创建Webview组件,设置JavaScript交互:`@Composable`函数`ComposableWebView`加载网页并启用JavaScript。通过`addJavascriptInterface`添加`WebAppInterface`类,允许JavaScript调用Android方法如播放音频。当页面加载完成时,执行`onWebViewReady`回调。
|
8月前
|
安全 物联网 测试技术
构建未来:Android与IoT设备的无缝交互深入探索软件自动化测试的未来趋势
【5月更文挑战第30天】在物联网(IoT)技术快速发展的当下,Android系统因其开放性和广泛的用户基础成为了连接智能设备的首选平台。本文将探讨如何通过现代Android开发技术实现智能手机与IoT设备的高效、稳定连接,并分析其中的挑战和解决方案。我们将深入挖掘Android系统的底层通信机制,提出创新的交互模式,并通过实例演示如何在Android应用中集成IoT控制功能,旨在为开发者提供一套可行的指导方案,促进IoT生态系统的进一步发展。
|
8月前
|
Android开发
Android使用ViewPager实现图片轮播系列之三:手动滑动 + 左右箭头(1)
Android使用ViewPager实现图片轮播系列之三:手动滑动 + 左右箭头(1)