Android仿微信底部按钮滑动变色
发布时间 - 2026-01-11 00:24:41 点击率:次Android仿微信底部按钮滑动变色,这里只针对使用Fragment为Tab页的滑动操作,进行简单的变色讲解。

首先说下OnPageChangeListener这个监听
//这个监听有三个方法 public abstract void onPageScrollStateChanged (int state) public abstract void onPageScrolled (int position, float positionOffset, int positionOffsetPixels) public abstract void onPageSelected (int position) //第一个方法onPageScrollStateChanged 中的参数state,有三个可取的值 public static final int SCROLL_STATE_DRAGGING Constant Value: 1 (0x00000001) //手指按在ViewPager上滑动时 public static final int SCROLL_STATE_IDLE Constant Value: 0 (0x00000000) //手指松开后,ViewPager自动滑动期间 public static final int SCROLL_STATE_SETTLING Constant Value: 2 (0x00000002) //ViewPager进入了某个Page //如果在onPageScrollStateChanged 中输出state的值,你会发现每次都是按顺序打印出“1---2---0” //第二个方法onPageScrolled的三个参数 position://滑动时,屏幕左侧显示的第一个page positionOffset://滑动比例,值的范围为[0, 1),手指往左滑动,该值递增,反之递减 positionOffsetPixels://滑动距离,和屏幕有关,手指往左滑动,该值递增,反之递减 //我们经常需要检查viewpager的滑动方向并作出一些操作,这时你只需要通过position和positionOffset两个值即可实现该功能。 //比如实现微信底部图标颜色渐变 向左滑动时 ChangeColorIconWithTextView left = mTabIndicator.get(position); //左侧显示的第一个page页面上底部图标和文字的初始化 ChangeColorIconWithTextView right = mTabIndicator.get(position + 1); //右侧显示的Page底部图标和文字的初始化 left.setIconAlpha(1 - positionOffset); //设置图标的透明度 此时positionOffset值递增 左侧图标的颜色变浅 right.setIconAlpha(positionOffset); //右侧图标的颜色逐渐变深 //第三个方法onPageSelected的三个参数 position://当前选择的page序号 //该方法被调用的时间比较特别,在上面的第一个方法中的“1---2----0”中的2执行之后,onPageSelected就执行,然后执行“1---2----0”中的0。就是手指松开屏幕之后,onPageSelected被执行。
上面提到了ChangeColorIconWithTextView 主要类
package com.mhealth.nursestation.app.pda.business.login.base.ui.fragmentutil;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Looper;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import com.mhealth.nursestation.app.pda.R;
/**
* 此类用于修改颜色渐变
*/
public class ChangeColorIconWithTextView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Paint mPaint;
/**
* 颜色
*/
private int mColor = 0XFF07B7C4;
/**
* 透明度 0.0-1.0 初始化必须是0 不是0就废了
*/
private float mAlpha = 0f;
/**
* 图标
*/
private Bitmap mIconBitmap;
/**
* 限制绘制icon的范围
*/
private Rect mIconRect;
/**
* icon底部文本
*/
private String mText = "微信";
private int mTextSize = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics());
private Paint mTextPaint;
private Rect mTextBound = new Rect();
public ChangeColorIconWithTextView(Context context) {
super(context);
}
/**
* 初始化自定义属性值
*
* @param context
* @param attrs
*/
public ChangeColorIconWithTextView(Context context, AttributeSet attrs) {
super(context, attrs);
// 获取设置的图标
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ChangeColorIconView);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.ChangeColorIconView_icon:
BitmapDrawable drawable = (BitmapDrawable) a.getDrawable(attr);
mIconBitmap = drawable.getBitmap();
break;
case R.styleable.ChangeColorIconView_color:
mColor = a.getColor(attr, 0x07B7C4);
break;
case R.styleable.ChangeColorIconView_text:
mText = a.getString(attr);
break;
case R.styleable.ChangeColorIconView_text_size:
mTextSize = (int) a.getDimension(attr, TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10,
getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
mTextPaint = new Paint();
mTextPaint.setTextSize(mTextSize);
mTextPaint.setColor(0xff07B7C4);
mTextPaint.setAntiAlias(true);
// 得到text绘制范围
mTextPaint.getTextBounds(mText, 0, mText.length(), mTextBound);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 得到绘制icon的宽
int bitmapWidth = Math.min(getMeasuredWidth() - getPaddingLeft()
- getPaddingRight(), getMeasuredHeight() - getPaddingTop()
- getPaddingBottom() - mTextBound.height());
int left = getMeasuredWidth() / 2 - bitmapWidth / 2;
int top = (getMeasuredHeight() - mTextBound.height()) / 2 - bitmapWidth
/ 2;
// 得到绘制icon的宽
mIconRect = new Rect(left, top, left + bitmapWidth, top + bitmapWidth);
}
@Override
protected void onDraw(Canvas canvas) {
int alpha = (int) Math.ceil((255 * mAlpha));
canvas.drawBitmap(mIconBitmap, null, mIconRect, null);
setupTargetBitmap(alpha);
drawSourceText(canvas, alpha);
drawTargetText(canvas, alpha);
canvas.drawBitmap(mBitmap, 0, 0, null);
}
private void setupTargetBitmap(int alpha) {
mBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setAlpha(alpha);
mCanvas.drawRect(mIconRect, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAlpha(255);
mCanvas.drawBitmap(mIconBitmap, null, mIconRect, mPaint);
}
/**
* 透明度 255
*
* @param canvas
* @param alpha
*/
private void drawSourceText(Canvas canvas, int alpha) {
mTextPaint.setTextSize(mTextSize);
mTextPaint.setColor(0x00333333);
mTextPaint.setAlpha(255 - alpha);
canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2
- mTextBound.width() / 2,
mIconRect.bottom + mTextBound.height(), mTextPaint);
}
private void drawTargetText(Canvas canvas, int alpha) {
mTextPaint.setColor(mColor);
mTextPaint.setAlpha(alpha);
canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2
- mTextBound.width() / 2,
mIconRect.bottom + mTextBound.height(), mTextPaint);
}
public void setIconAlpha(float alpha) {
this.mAlpha = alpha;
invalidateView();
}
private void invalidateView() {
if (Looper.getMainLooper() == Looper.myLooper()) {
invalidate();
} else {
postInvalidate();
}
}
public void setIconColor(int color) {
mColor = color;
}
public void setIcon(int resId) {
this.mIconBitmap = BitmapFactory.decodeResource(getResources(), resId);
if (mIconRect != null)
invalidateView();
}
public void setIcon(Bitmap iconBitmap) {
this.mIconBitmap = iconBitmap;
if (mIconRect != null)
invalidateView();
}
private static final String INSTANCE_STATE = "instance_state";
private static final String STATE_ALPHA = "state_alpha";
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
bundle.putFloat(STATE_ALPHA, mAlpha);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mAlpha = bundle.getFloat(STATE_ALPHA);
super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
} else {
super.onRestoreInstanceState(state);
}
}
}
在Activity里面实现监听操作
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (positionOffset > 0) {
ChangeColorIconWithTextView left = mTabIndicator.get(position);
ChangeColorIconWithTextView right = mTabIndicator.get(position + 1);
left.setIconAlpha(1 - positionOffset);
right.setIconAlpha(positionOffset);
}
}
定义一个集合,将所有变色控件装载进去
private List<ChangeColorIconWithTextView> mTabIndicator = new ArrayList<ChangeColorIconWithTextView>();
private void initTabIndicator() {
ChangeColorIconWithTextView one = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_one);
ChangeColorIconWithTextView two = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_two);
ChangeColorIconWithTextView three = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_three);
ChangeColorIconWithTextView four = (ChangeColorIconWithTextView) findViewById(R.id.id_indicator_four);
mTabIndicator.add(one);
mTabIndicator.add(two);
mTabIndicator.add(three);
mTabIndicator.add(four);
one.setOnClickListener(this);
two.setOnClickListener(this);
three.setOnClickListener(this);
four.setOnClickListener(this);
one.setIconAlpha(1.0f);
}
点击监听
@Override
public void onClick(View v) {
resetOtherTabs();
switch (v.getId()) {
case R.id.id_indicator_one:
mTabIndicator.get(0).setIconAlpha(1.0f);
mViewPager.setCurrentItem(0, false);
break;
case R.id.id_indicator_two:
mTabIndicator.get(1).setIconAlpha(1.0f);
mViewPager.setCurrentItem(1, false);
break;
case R.id.id_indicator_three:
mTabIndicator.get(2).setIconAlpha(1.0f);
mViewPager.setCurrentItem(2, false);
mAppContext.has_new_talk = false;
break;
case R.id.id_indicator_four:
mTabIndicator.get(3).setIconAlpha(1.0f);
mViewPager.setCurrentItem(3, false);
break;
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Android
# 微信
# 滑动变色
# Android自定义Seekbar滑动条 Pop提示跟随滑动按钮滑动
# Android编程之滑动按钮事件实例详解
# Android编程实现滑动按钮功能详解
# 自定义滑动按钮为例图文剖析Android自定义View绘制
# 如何在Android中实现渐显按钮的左右滑动效果
# Android自定义实现可滑动按钮
# 第一个
# 都是
# 往左
# 第二个
# 此类
# 自定义
# 在上面
# 第三个
# 你会发现
# 大家多多
# 废了
# 你只需要
# 变浅
# os
# Bundle
# super
# param
# context
# AttributeSet
# mTextBound
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
大型企业网站制作流程,做网站需要注册公司吗?
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
Laravel Admin后台管理框架推荐_Laravel快速开发后台工具
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
如何用AI帮你把自己的生活经历写成一个有趣的故事?
如何在腾讯云服务器上快速搭建个人网站?
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
在线制作视频网站免费,都有哪些好的动漫网站?
大同网页,大同瑞慈医院官网?
如何在万网利用已有域名快速建站?
详解Android图表 MPAndroidChart折线图
laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法
使用spring连接及操作mongodb3.0实例
Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】
Laravel如何实现API版本控制_Laravel版本化API设计方案
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
如何解决hover在ie6中的兼容性问题
HTML 中动态设置元素 name 属性的正确语法详解
如何在宝塔面板创建新站点?
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
如何快速查询网站的真实建站时间?
中山网站推广排名,中山信息港登录入口?
网易LOFTER官网链接 老福特网页版登录地址
Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID
Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
香港网站服务器数量如何影响SEO优化效果?
简单实现Android文件上传
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
如何用PHP工具快速搭建高效网站?
Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】
Laravel如何使用.env文件管理环境变量?(最佳实践)
网站制作报价单模板图片,小松挖机官方网站报价?
百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
简历没回改:利用AI润色让你的文字更专业
如何在VPS电脑上快速搭建网站?
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
Python3.6正式版新特性预览
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Laravel中的withCount方法怎么高效统计关联模型数量
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
高防服务器如何保障网站安全无虞?
Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】
Laravel DB事务怎么使用_Laravel数据库事务回滚操作

