android使用Tab效果滑动
android使用Tab效果滑动
使用SlidingTabLayout
这是android L
最新的使用tab
的效果,Google Play
的应用
教程:Google Play Style Tabs using SlidingTabLayout,挺详细的教程
通过这篇:SlidingTabLayout的使用--替代ActionBar的Tab导航,可以知道
- 样式:直接在
xml
上的SlidingTabLayout
上改,他是继承HorizontalScrollView
的,可以通过background
来设置颜色 - 加入
custom_tab.xml
的时候,是代表tab
使用图标 - 改
tab
中的字体颜色,参考这里:Custom selected tab text color in SlidingTabLayout - 改下划线的颜色:
第一种方式:
slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.tab_text_color));
第二种方式
slidingTabLayout.setCustomTabColorizer(new SlidingTabLayout.TabColorizer(){ @Override public int getIndicatorColor(int position) { return Color.WHITE; } });
- 想改
Tab
点击的效果,发现slidingTabLayout
的createDefaultTabView
方法,是根据设定的Theme
来进行改变的。 - 如何使用在
Fragment
中的静态方法newInstance
传递数据呢
思路:通过Bundle
进行传递,在oncreate
方法中使用getArguments()
方法得到,另一种方式是通过fragment.title
的方式来改变成员变量的值
public static final String BG_PAGE="BgManagerFragment"; public static final String FRAGMENT_TITLE="tilte"; private int mPage; private String title; public BgManagerFragment() { // Required empty public constructor } public static BgManagerFragment newInstance(String title,int page){ Bundle args = new Bundle(); args.putInt(BG_PAGE, page); args.putString(FRAGMENT_TITLE, title); BgManagerFragment fragment = new BgManagerFragment(); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPage=getArguments().getInt(BG_PAGE);//在newInstance方法中通过Bundle进行传递值 title=getArguments().getString(FRAGMENT_TITLE); }
另一种,只列出newInstance()
方法
public static BgManagerFragment newInstance(String title,int page){ BgManagerFragment fragment = new BgManagerFragment(); fragment.title=title; fragment.mPage=page; return fragment;}
- 如何让不同的
fragment
加载不同数据,进行不同的显示。通过别人的案例,可以知道需要对adapter
和Fragment
进行修改
添加图标到tab
private int[] imageResId = { R.drawable.ic_one, R.drawable.ic_two, R.drawable.ic_three}; // ... @Override public CharSequence getPageTitle(int position) { // Generate title based on item position // return tabTitles[position]; Drawable image = context.getResources().getDrawable(imageResId[position]); image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight()); SpannableString sb = new SpannableString(" "); ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM); sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return sb;}
注意
但是由于
SlidingTabLayout
自带的TextView
会调用setAllCaps(true)
,会取消所有的 ImageSpan 的效果。所以需要自定义TabView。
接着:
在 tab.setViewPager(pager)
之前调用 tab.setCustomTabView(R.layout.custom_tab,0)
设置自定义TabView。
tab.setCustomTabView(R.layout.custom_tab,0);tab.setViewPager(pager);
如果要每个TabView都平分屏幕宽度,只需在自定义的TextView 上加上权重属性即可;
android:layout_weight="1"
通过以上方式,是实现了显示图标,但是selector
的效果完全没有了,那么如何解决?
参考:ADeveloper: Add Icons to SlidingTabLayout instead of Text的答案5.
和这个Add Icons to SlidingTabLayout instead of Text,只有三个赞成的答案,得到启发。
第一种解决方式:
按照stackoverflow
来,就可以解决了
第一步:修改适配器FragmentPagerAdapter
public class ClubMemberManagerAdapter extends FragmentPagerAdapter {private int[] imageResId = {R.drawable.tab_select_home,R.drawable.tab_select_act,R.drawable.tab_select_data};//添加一个获取资源的方法public int getDrawableId(int position){ //Here is only example for getting tab drawables return imageResId[position];}//下面这个方法,是为了不让字体消失出来@Overridepublic CharSequence getPageTitle(int position) { Drawable image = context.getResources().getDrawable(imageResId[position]); image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight()); SpannableString sb = new SpannableString(" "); ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM); sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return sb;}
第二步:
那么相应的加载SlidingTabLayout
的Activity/fragment
就不需要这句
//slidingTabLayout.setCustomTabView(R.layout.custom_tab, 0);
第三步:
修改SlidingTabLayout
的populateTabStrip()
方法
private void populateTabStrip() { //强制转换成ClubMemberManagerAdapter,为了得到ClubMemberManagerAdapter下的得到资源的方法:getDrawableId final ClubMemberManagerAdapter adapter = (ClubMemberManagerAdapter)mViewPager.getAdapter(); final OnClickListener tabClickListener = new TabClickListener(); for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; TextView tabTitleView = null; if (mTabViewLayoutId != 0) { tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false); tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId); } if (tabView == null) { //默认是生成TextView tabView = createDefaultTabView(getContext()); } if (tabImageView == null && TextView.class.isInstance(tabView)) { //这里依然是TextView.class.的判断父系 tabImageView = (ImageView) tabView; } if (mDistributeEvenly) { LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams(); lp.width = 0; lp.weight = 1; } tabTitleView.setCompoundDrawablesWithIntrinsicBounds(0,adapter.getDrawableId(i), 0, 0); //上面这句是TexView加载资源的方式,参数为(左,上,右,下) tabTitleView.setText(adapter.getPageTitle(i)); tabTitleView.setTextColor(Color.WHITE); tabView.setOnClickListener(tabClickListener); String desc = mContentDescriptions.get(i, null); if (desc != null) { tabView.setContentDescription(desc); } mTabStrip.addView(tabView); if (i == mViewPager.getCurrentItem()) { tabView.setSelected(true); } }}
通过上面的配置会发现,图标的selector
效果有了,但是毕竟是TextView,虽然没有字体,但还是会继续占位置,效果依然不理想。所以...
第二种解决方式:直接将TextView
改成ImageView
便可以。
第一步:同理,依然需要资源
public class ClubMemberManagerAdapter extends FragmentPagerAdapter {public int getDrawableId(int position){ //Here is only example for getting tab drawables return imageResId[position];//图标资源}@Overridepublic CharSequence getPageTitle(int position) { return tabTitles[position];//使用imageview,这个只是一个摆设而已}}
第二步,依然是修改SlidingTabLayout
的方法populateTabStrip
private void populateTabStrip() { //强制转换成ClubMemberManagerAdapter,为了得到ClubMemberManagerAdapter下的得到资源的方法:getDrawableId final ClubMemberManagerAdapter adapter = (ClubMemberManagerAdapter)mViewPager.getAdapter(); final OnClickListener tabClickListener = new TabClickListener(); for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; ImageView tabImageView = null; if (mTabViewLayoutId != 0) { // If there is a custom tab view layout id set, try and inflate it tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false); tabImageView = (ImageView) tabView.findViewById(mTabViewTextViewId); } if (tabView == null) { //改成ImageView生成方式 tabView = createImageViewTabView(getContext()); } if (tabImageView == null && ImageView.class.isInstance(tabView)) { //这里是ImageView.class.的判断父系,因为改成ImageView的生成方式 tabImageView = (ImageView) tabView; } if (mDistributeEvenly) { LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams(); lp.width = 0; lp.weight = 1; } //加载图标资源 tabImageView.setImageResource(adapter.getDrawableId(i)); tabView.setOnClickListener(tabClickListener); String desc = mContentDescriptions.get(i, null); if (desc != null) { tabView.setContentDescription(desc); } mTabStrip.addView(tabView); if (i == mViewPager.getCurrentItem()) { tabView.setSelected(true); } }}
第三步,就是方法createImageViewTabView
是怎么实现的呢
protected ImageView createImageViewTabView(Context context){ ImageView imageView = new ImageView(context); imageView.setLayoutParams(new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); TypedValue outValue = new TypedValue(); getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);//使用系统的主题 imageView.setBackgroundResource(outValue.resourceId); int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density); imageView.setPadding(padding, padding, padding, padding); return imageView;}
改成这种imageview后,感觉已经将SlidingTabLayout
改成了自能加载ImageView的类了。
用另一种的实现
Sliding Tabs with PagerSlidingTabStrip
Fragment上使用Tab
参考:ActionBar Tabs with Fragments
更多相关文章
- Android下使用TelephonyManager类获取设备电话相关信息
- 【Android(安卓)开发教程】编码实现获取与修改预设信息中的值
- Android(安卓)在JNI中执行Java方法--C/C++调用Java
- android 面试
- Android学习笔记•从零开始•第二天•Intent-穿梭在Activity之间
- android中 Button 安装监听的三种形式
- android 动画原理源码分析之Animation
- Android两种不同的方法去实现图像的放大与缩小(很有帮助)
- Android(安卓)Studio 找不到R文件解决方法汇总