您的位置:首页 > 移动开发 > Android开发

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

2015-10-06 20:16 621 查看

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: