笔记:Android自定义按钮涟漪效果
来源:互联网 发布:2016年7月淘宝新政策 编辑:程序博客网 时间:2024/05/21 05:37
目标
1.创建一个类继承Button并重写onDraw方法
2.创建一个类继承Drawable,在类中实现以下目标
- 能设定颜色,透明度
- 点击画圆
- 自动淡出圆的动画效果
首先创建Button类代码如下:
public class RippleButton extends android.suppert.v7.widget.AppCompatButton { private RippleDrawable mRippleDrawable; public RippleButton(Context context){ this(context,null); } public RippleButton(Context context,AttributeSet attrs){ this(context,attrs,0); } public RippleButton(Context context,AttributSet attrs,int defStyleAttr){ super(context,attrs,defStyleAttr); mRippleDrawable = new RippleDrawable(); } protected void onDraw(Canvas canvas){ super.onDraw(canvas); mRippleDrawable.draw(canvas); }}
创建Drawable类,实现draw方法:
public class RippleDrawable extends Drawable{ public RippleDrawable(){ } public void draw(Canvas canvas){ }}
布局设置:
background背景图可放不可放.
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.test.android.customviewtest.MainActivity"> <com.test.android.customviewtest.RippleButton android:layout_width="match_parent" android:layout_height="400dp" android:layout_centerInParent="true" android:background="@drawable/ba" android:gravity="center" android:text="Ripple Button" android:textColor="@color/colorPrimary" /></RelativeLayout>
接下来画涟漪的圆在RippleDrawable类中:
public class RippleDrawable extends Drawable{ private int mRippleColor = 0; private int mAlpha = 255; private Paint mPaint = new Paint(); private float mRipplePointX, mRipplePointY;//圆心坐标 private float mRippleRadios = 0;//半径 public RippleDrawable() { mPaint.setAntiAlias(true);//开启抗锯齿,抗平滑 mPaint.setDither(true);//开启防抖动 setRippleColor(Color.RED);//设置涟漪圆的颜色 //滤镜,可以根据需求来,也可以不设// setColorFilter(new LightingColorFilter(0xFFFF0000,0x00330000)); } private int mPaintAlpha = 255; private int mBackgroundColor; public void draw(Canvas canvas){ mPaint.setAlpha(mPaintAlpha); canvas.drawColor(mBackgroundColor); canvas.drawCircle(mRipplePointX,mRipplePointY,mRippleRadios,mPaint); } @Override public void setAlpha(@IntRange(from = 0, to = 255) int alpha) { mAlpha = alpha; onColorOrAlphaChange(); } @Override public int getAlpha() { return mAlpha; } public void setRippleColor(int color){ mRippleColor = color; onColorOrAlphaChange(); } public void onColorOrAlphaChange(){ mPaint.setColor = mRippleColor; if(mAlpha != 255){ int pAlpha = mPaint.getAlpha(); int realAlpha = (int)(pAlpha * (mAlpha/255f)); mPaint.setAlpha(realAlpha); mPaint.getColor(); } invalidateSelf(); } @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { if (mPaint.getColorFilter() != colorFilter) { mPaint.setColorFilter(colorFilter); invalidateSelf(); } } @Override public int getOpacity() { int alpha = mPaint.getAlpha(); if (alpha == 255) { return PixelFormat.OPAQUE; } else if (alpha == 0) { return PixelFormat.TRANSPARENT; } else { return PixelFormat.TRANSLUCENT; } }}
点击事件:
RippleButtion类
圆点击事件实现刷新需要3步
public class RippleButton extends android.support.v7.widget.AppCompatButton {......public RippleButton(Context context, AttributeSet attrs, int defStyleAttr) { ...... //1.设置刷新回调 mRippleDrawable.setCallback(this); } @Override protected boolean verifyDrawable(@NonNull Drawable who) { //2.验证drawable是否OK return who == mRippleDrawable || super.verifyDrawable(who); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //3.设置drawable重绘和刷新的区域 mRippleDrawable.setBounds(0, 0, getWidth(), getHeight()); } @Override public boolean onTouchEvent(MotionEvent event) { mRippleDrawable.onTouch(event); super.onTouchEvent(event); return true; }}
RippleDrawable中要实现点击事件,进\退出动画
//用户是否抬起 private boolean mTouchRelease; public void onTouch(MotionEvent event) { //getAction()封装了点击的详细信息,是点击抬起还是按下的操作,同时包括点击的坐标信息. //getActionMasked()仅仅只保留了点击的操作 switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: onTouchDown(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: onTouchMove(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: onTouchUp(event.getX(), event.getY()); break; case MotionEvent.ACTION_CANCEL: onTouchCancel(event.getX(), event.getY()); break; } } private void onTouchDown(float x, float y) { mDonePointX = x; mDonePointY = y; mRippleRadios = 0; mTouchRelease = false; startEnterRunnable();// mRunnable.run(); } private void onTouchMove(float x, float y) { } private void onTouchUp(float x, float y) { mTouchRelease = true; if (mEnterDone) startExitRunnable(); } private void onTouchCancel(float x, float y) { mTouchRelease = true; if (mEnterDone) startExitRunnable(); } private boolean mEnterDone; private float mEnterProgress = 0; //动画查看器,用于实现从快到慢的效果 private Interpolator mEnterInterpolator = new DecelerateInterpolator(2); private Runnable mRunnable = new Runnable() { @Override public void run() { mEnterProgress = mEnterProgress + 0.01f; if (mEnterProgress > 1) { onEnterDone(); return; } float realProgress = mEnterInterpolator.getInterpolation(mEnterProgress); onEnterProgress(realProgress); scheduleSelf(this, SystemClock.currentThreadTimeMillis() + 16); } }; private void onEnterDone() { mEnterDone = true; if (mTouchRelease) { startExitRunnable(); } } private void onEnterProgress(float progress) { float maxRadius = Math.max(mCenterPointX, mCenterPointY); mRippleRadios = getProgresValue(0f, maxRadius, progress); mRipplePointX = getProgresValue(mDonePointX, mCenterPointX, progress); mRipplePointY = getProgresValue(mDonePointY, mCenterPointY, progress); int alpha = (int) getProgresValue(0, 64, progress); mBackgroundColor = changeColorAlpha(0x00000000, alpha); invalidateSelf(); } //启动进入动画 private void startEnterRunnable() { mPaintAlpha = 255; mEnterDone = false; mEnterProgress = 0; unscheduleSelf(mExitRunnable); unscheduleSelf(mRunnable); scheduleSelf(mRunnable, SystemClock.uptimeMillis()); } //启动退出动画 private void startExitRunnable() { mExitProgress = 0; unscheduleSelf(mRunnable); unscheduleSelf(mExitRunnable); scheduleSelf(mExitRunnable, SystemClock.uptimeMillis()); } //退出动画进度值 private float mExitProgress = 0; //动画查看器,用于实现从慢到快的效果 private Interpolator mExitInterpolator = new AccelerateInterpolator(2); private Runnable mExitRunnable = new Runnable() { @Override public void run() { mExitProgress = mExitProgress + 0.01f; if (mExitProgress > 1) { onExitDone(); return; } float realProgress = mExitInterpolator.getInterpolation(mExitProgress); onExitProgress(realProgress); scheduleSelf(this, SystemClock.currentThreadTimeMillis() + 16); } }; private void onExitDone() { } /* 退出动画刷新方法 */ private void onExitProgress(float progress) {// float maxRadius = Math.max(mCenterPointX,mCenterPointY);// mRippleRadios = getProgresValue(maxRadius,0f,progress); int alpha = (int) getProgresValue(64, 0, progress); mBackgroundColor = changeColorAlpha(0x00000000, alpha); mPaintAlpha = (int) getProgresValue(255, 0, progress); invalidateSelf(); } private float getProgresValue(float start, float end, float progress) { return start + (end - start) * progress; } //按下时的点 private float mDonePointX, mDonePointY; //控件的中心点 private float mCenterPointX, mCenterPointY; @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mCenterPointX = bounds.centerX(); mCenterPointY = bounds.centerY(); } private int changeColorAlpha(int color, int alpha) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = (color) & 0xFF; return (alpha << 24) | (r << 16) | (g << 8) | b; }
阅读全文
0 0
- 笔记:Android自定义按钮涟漪效果
- Android长按Button按钮,产生涟漪效果
- Android自定义View之雷达涟漪效果(附带demo)
- 自定义点击产生涟漪效果
- Android自定义按钮点击效果
- android的Material Design点击涟漪效果
- Android自定义View之蓝牙搜索的涟漪雷达效果: 我在搜索呢,你在哪里呀?
- Android 自定义带阴影效果按钮
- android的多点触摸(制作水波涟漪效果)
- 兼容Android API 2.X的涟漪点击效果
- android水波纹涟漪效果的实现<入门+初步提高>
- CSS3 涟漪效果
- Shader水涟漪效果
- android开发笔记之自定义开关按钮
- Android自定义带有阴影效果的按钮Demo
- Android自定义标题和按钮效果(附源码)
- Android 5.0+ 自定义普通按钮的ripple波纹效果
- Android 5.0+ 自定义普通按钮的ripple波纹效果
- bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 最小割
- Linux/MacOS 中同时安装OpenCV2和OpenCV3并快速切换
- 湖北民族学院oj1800之 矩形与圆
- Java变量名的命名方式
- Kotlin 成了 Android 开发的官方语言
- 笔记:Android自定义按钮涟漪效果
- python urllib2遇到Content-Encoding=gzip解码为乱码的解决方案
- JUnit 4 与 TestNG 对比
- prepare hdf5 data for training
- vue成长之路+实战+Vue2+VueRouter2+webpack(一)vue-router路由入门
- POJ-2229-Sumsets -(简单dp)
- Java反射
- 湖北民族学院oj1829之 软件版本
- Policy Gradient Methods in Reinforcement Learning