自定义view实现android5.0 ripple效果
2015-11-14 21:40
507 查看
思路:
重写Button在onTouchEvent中监听action_down事件,然后播放一个属性动画,动态的改变圆圈的半径,这样就产生了波纹效果
1.首先是RippleButton直接继承自Button
2.在attrs.xml中自定义两个属性一个是波纹的颜色rb_rippleColor,一个是波纹的透明度rb_alphaFactor;
3.在构造函数中初始化这两个属性
4.重写onTouchEvent
5.实现setRadius方法
6.更新view
7.最后是给动画结束添加一个回调函数
源码地址:https://github.com/zlidentify/RippleButton
参考实现:https://github.com/siriscac/RippleView
重写Button在onTouchEvent中监听action_down事件,然后播放一个属性动画,动态的改变圆圈的半径,这样就产生了波纹效果
1.首先是RippleButton直接继承自Button
2.在attrs.xml中自定义两个属性一个是波纹的颜色rb_rippleColor,一个是波纹的透明度rb_alphaFactor;
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RippleView"> <attr name="rb_rippleColor" format="color" /> <attr name="rb_alphaFactor" format="float" /> </declare-styleable> </resources>
3.在构造函数中初始化这两个属性
public RippleButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setAlpha(100); mPath = new Path(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RippleView); mRippleColor = a.getColor(R.styleable.RippleView_rb_rippleColor, mRippleColor); mAlphaFactor = a.getFloat(R.styleable.RippleView_rb_alphaFactor, mAlphaFactor); if (mAlphaFactor > 0 && mAlphaFactor <= 1) { mPaint.setAlpha((int) Math.floor(255 * mAlphaFactor)); } a.recycle(); }
4.重写onTouchEvent
public boolean onTouchEvent(MotionEvent event) { boolean superResult = super.onTouchEvent(event); mDownX = event.getX(); mDownY = event.getY(); if (isEnabled() && !isAnimatorPlaying && event.getActionMasked() == MotionEvent.ACTION_DOWN) { //calculate ripple's radius float offsetX = Math.max(mDownX - getLeft(), getRight() - mDownX); float offsetY = Math.max(mDownY - getTop(), getBottom() - mDownY); mMaxRadius = (float) Math.sqrt(Math.pow(offsetX, 2) + Math.pow(offsetY, 2)); ObjectAnimator mScaleAnimator = ObjectAnimator.ofFloat(this, "radius", 0, mMaxRadius); mScaleAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { isAnimatorPlaying = true; } @Override public void onAnimationEnd(Animator animation) { setRadius(0); isAnimatorPlaying = false; if (onRippleFinished != null) { onRippleFinished.onRippleFinished(RippleButton.this); } } @Override public void onAnimationCancel(Animator animation) { isAnimatorPlaying = false; } @Override public void onAnimationRepeat(Animator animation) { } }); mScaleAnimator.setInterpolator(new AccelerateInterpolator()); mScaleAnimator.setDuration(500); mScaleAnimator.start(); } return superResult; }这里边主要是对手指按下这个事件作出了相应,给一个属性动画,也就是对半径作出改变,下面一个重要的方法就是setRadius(float radius)
5.实现setRadius方法
protected void setRadius(float radius) { mMaxRadius = radius; if (radius > 0) { RadialGradient mRadialGradient = new RadialGradient(mDownX, mDownY, radius, adjustAlpha(mRippleColor, mAlphaFactor), mRippleColor, Shader.TileMode.MIRROR); mPaint.setShader(mRadialGradient); } invalidate(); }这里面是根据属性动画里不断传递过来的半径,对RadialGradient不断的改变其大小,然后重新绘制真个view
6.更新view
protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isInEditMode()) { return; } canvas.save(Canvas.CLIP_SAVE_FLAG); mPath.reset(); mPath.addCircle(mDownX, mDownY, mMaxRadius, Path.Direction.CW); canvas.clipPath(mPath); canvas.restore(); canvas.drawCircle(mDownX, mDownY, mMaxRadius, mPaint); }这里面主要就是根据panint画出一个圆,这样就实现了ripple效果啦
7.最后是给动画结束添加一个回调函数
public interface OnRippleFinished { void onRippleFinished(View rippleButton); }
public void setOnRippleFinished(OnRippleFinished onRippleFinished) { this.onRippleFinished = onRippleFinished; }
源码地址:https://github.com/zlidentify/RippleButton
参考实现:https://github.com/siriscac/RippleView
相关文章推荐
- Android 组合控件
- Windows环境下Android Studio v1.0安装教程
- android中Serializable 和 Parcelable 的区别
- Android创建前台运行的Service(不会被系统杀死)
- Android之混淆代码总结
- Android中Xml工具类的封装
- android图片等比例缩放 填充屏幕
- android图片压缩问题
- Android 学习之ImageView自适应
- Android开发中adb启动失败adb连接异常的解决办法
- Android Studio编译好的apk放在哪里
- android dispatchTouchEvent()事件分发机制
- Android之如何解决android.os.NetworkOnMainThreadException的异常
- Android开发手记(26) Java多线程的实现
- Android IBinder机制简单介绍
- Android开发Vitamio开发框架Audio音频播放失败
- Android:res之shape制作圆角、虚线、渐变
- [Android Pro] synchronized与static synchronized 的区别
- android hal 学习——编写android内核驱动
- android 计时器线程