Android自定义Viewpager指示器PagerIndicator-仿微博头条效果

本文主要是介绍Android自定义Viewpager指示器PagerIndicator-仿微博头条效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

平时工作之余,喜欢看看新闻,手机难免会装了几个新闻阅读类的app。新闻类的app风格大致一致,可以选择不同栏目,栏目可以切换。最近就在用微博头条,感觉界面挺清新的。而且它使用的PagerIndicator挺好看的。昨晚居然准时下班了,趁着早就实现了下。今天用博客好好记录下

上图

图片描述

效果分析

1 每个tab都包含色块和文字,而且文字的显示个数不同

2 文字:由未选中到被选中的文字颜色从黑色变成白色;由选中到未被选中的文字颜色从白色变成黑色

3 色块:由未选中到被选中的色块显示高度越来越大;由选中到未被选中的色块显示高度越来越小

4 让处于中间的tab自动滑动到中间显示

实现思路

1 tab实现

1.1 自定义UpDownView,该View继承RelativeLayout

1.2 文字使用TextView显示,色块使用ImageView显示

public UpDownView(Context context, AttributeSet attrs) {super(context, attrs);imageView = new ImageView(context);// 设置ImageView的大小为每个父View(tab)的大小LayoutParams imageParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);addView(imageView, imageParams);textView = new TextView(context);// 设置TextView的文字居中显示textView.setGravity(Gravity.CENTER);// 设置TextView的高度为每个父View(tab)的高度LayoutParams textParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);textParams.addRule(RelativeLayout.CENTER_IN_PARENT);textView.setPadding(40, 10, 40, 10);addView(textView, textParams);
}

1.3 ImageView显示设置

// 当控件的宽高发生变化时回调该方法,可在这里获取控件的高度
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);height = textView.getMeasuredHeight();// 通过setTranslationY让ImageView开始时只显示总高度的0.2fimageView.setTranslationY((int) (height * 0.8f));LayoutParams imageParams = (LayoutParams) imageView.getLayoutParams();imageParams.width = textView.getMeasuredWidth();
}

1.4 该View对外提供的方法

// 设置ImageView的颜色
public void setImageColor(int color) {imageView.setImageResource(color);
}
// 设置文字
public void setText(String text) {textView.setText(text);
}
// 设置文字的颜色
public void setTextColor(int color) {textView.setTextColor(color);
}
// 显示色块
public void show() {ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,"translationY", 0);objectAnimator.setDuration(300);objectAnimator.start();
}
// 设置ImageView的偏移量,即改变色块显示的高度
public void setTranslation(float direction) {imageView.setTranslationY(direction);
}
// 隐藏色块
public void hide() {ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,"translationY", (int) (height * 0.8f));objectAnimator.setDuration(300);objectAnimator.start();
}
// 主要用于获取当前色块所在的位置
public int getmIndex() {return mIndex;
}

2 PagerIndicator指示器的实现

2.1 指示器可以装载很多的tab,而且支持横向滑动,于是可以选择继承HorizontalScrollView

2.2 由于HorizontalScrollView只能有一个子View,所以在初始化的时候,为该View添加一个默认的子View,当需要添加tab时,将其添加到默认的子View中即可。

public PagerIndicatorTwo(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;// 设置横向滚动条不显示setHorizontalScrollBarEnabled(false);// 添加一个LinearLayout作为默认的子ViewlinearLayout = new LinearLayout(context);linearLayout.setOrientation(LinearLayout.HORIZONTAL);LayoutParams liLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);addView(linearLayout, liLayoutParams);
}

2.3 与ViewPager绑定

public void setmViewPager(ViewPager viewPager) {this.mViewPager = viewPager;if (mViewPager.getAdapter() == null) {throw new NullPointerException();}// 该PagerIndicator实现了OnPageChangeListener接口,当ViewPager发生变化时,会回调OnPageChangeListener相应的方法,通过这些方法,可以完成指示器相应的变化this.mViewPager.setOnPageChangeListener(this);
}

2.4 设置tab

public void setIndicators(List<String> indicators) {this.indicators.clear();this.indicators.addAll(indicators);linearLayout.removeAllViews();// 创建对应个数的UpDownView,并添加到linearLayout中去for (int i = 0; i < indicators.size(); i++) {UpDownView upDownView = new UpDownView(context);upDownView.setGravity(Gravity.CENTER);upDownView.setImageColor(colors[i % 3]);// 设置每个tab所在的位置upDownView.mIndex = i;upDownView.setText(indicators.get(i));// 为每个tab增加点击事件upDownView.setOnClickListener(onTadClickListener);LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);linearLayout.addView(upDownView, params);}requestLayout();
}

2.5 tab点击事件

private OnClickListener onTadClickListener = new OnClickListener() {@Overridepublic void onClick(View view) {tabClick = true;UpDownView upDownView = (UpDownView) view;// 获取到tab所在的位置,调用ViewPager的setCurrentItem切换页面mViewPager.setCurrentItem(upDownView.mIndex);}
};

2.6 onPageScrolled的回调(即滑动ViewPager产生的变化处理):该方法有三个参数,通过这三个参数的变化,改变每个tab对应的变化即可;这里有个学习点,就是颜色的变化可以通过ArgbEvaluator这个类实现

leftDownView = (UpDownView) linearLayout.getChildAt(arg0);
rightDownView = (UpDownView) linearLayout.getChildAt(arg0 + 1);
// 色条变化
leftDownView.setTranslation(arg1 * leftDownView.height * 0.8f);
rightDownView.setTranslation((1 - arg1) * rightDownView.height* 0.8f);
// 文字颜色变化
int leftColor = (Integer) new ArgbEvaluator().evaluate(arg1,Color.WHITE, Color.BLACK);
leftDownView.setTextColor(leftColor);
int rightColor = (Integer) new ArgbEvaluator().evaluate(1 - arg1,Color.WHITE, Color.BLACK);
rightDownView.setTextColor(rightColor);

2.7 自动滑动到中间位置

// 当某一项被选中时会回调onPageSelected方法,在这里我们可以让该PagerIndicator自动滚动:这里主要涉及到移动距离的计算
public void changePager(final int last) {final UpDownView lastChild = (UpDownView) linearLayout.getChildAt(last);int[] location = new int[2];lastChild.getLocationOnScreen(location);final int scrollPos = location[0]- (getMeasuredWidth() - lastChild.getMeasuredWidth()) / 2;smoothScroll(scrollPos, new AnimatorListenerAdapter() {});}

3 外边调用OnPageChangeListener问题

由于该PagerIndicator需要根据OnPageChangeListener的回调变化,所以需要在PagerIndicator中实现该接口,并设置给ViewPager。这就产生个问题,假如项目在使用ViewPager时也需要根据OnPageChangeListener的回调进行某些处理该怎么处理。这个问题可以这样子处理

3.1 在项目中,不调用ViewPager.setOnPageChangeListener,而是PagerIndicator.setOnPageChangeListener,即将回调设置给PagerIndicator,这样就可以正常监听该接口了

3.2 看内部处理

// 将传递进来的OnPageChangeListener对象保存到onPageChangeListener中
private OnPageChangeListener onPageChangeListener;public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) {this.onPageChangeListener = onPageChangeListener;
}
// 当PagerIndicator中的onPageScrollStateChanged方法被调用时,我们手动调用传进来的onPageChangeListener的onPageScrollStateChanged(arg0)方法,其他回调方法一样
@Override
public void onPageScrollStateChanged(int arg0) {if (mViewPager.getAdapter().getCount() != indicators.size()) {return;}onPageChangeListener.onPageScrollStateChanged(arg0);
}

总结

至此,一个仿微博头条效果的PagerIndicator就实现了。当然我们可以自定义一些属性,例如文字颜色和大小,ImageView的颜色等,用于设置想要的一些显示。提高该View的灵活性

这篇关于Android自定义Viewpager指示器PagerIndicator-仿微博头条效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/414393

相关文章

基于Python实现PDF动画翻页效果的阅读器

《基于Python实现PDF动画翻页效果的阅读器》在这篇博客中,我们将深入分析一个基于wxPython实现的PDF阅读器程序,该程序支持加载PDF文件并显示页面内容,同时支持页面切换动画效果,文中有详... 目录全部代码代码结构初始化 UI 界面加载 PDF 文件显示 PDF 页面页面切换动画运行效果总结主

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

使用Python实现生命之轮Wheel of life效果

《使用Python实现生命之轮Wheeloflife效果》生命之轮Wheeloflife这一概念最初由SuccessMotivation®Institute,Inc.的创始人PaulJ.Meyer... 最近看一个生命之轮的视频,让我们珍惜时间,因为一生是有限的。使用python创建生命倒计时图表,珍惜时间

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

防近视护眼台灯什么牌子好?五款防近视效果好的护眼台灯推荐

在家里,灯具是属于离不开的家具,每个大大小小的地方都需要的照亮,所以一盏好灯是必不可少的,每个发挥着作用。而护眼台灯就起了一个保护眼睛,预防近视的作用。可以保护我们在学习,阅读的时候提供一个合适的光线环境,保护我们的眼睛。防近视护眼台灯什么牌子好?那我们怎么选择一个优秀的护眼台灯也是很重要,才能起到最大的护眼效果。下面五款防近视效果好的护眼台灯推荐: 一:六个推荐防近视效果好的护眼台灯的