本文实例为大家分享了Android 5.0 实现水波扩散效果的具体代码,供大家参考,具体内容如下
该效果是通过自定义界面来实现的
1、首先自定义属性,attrs.xml代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RippleView"> <attr name="rippleColor" format="color" /> <attr name="rippleAlpha" format="float" /> <attr name="maskAlpha" format="float" /> <attr name="rippleTime" format="integer" /> </declare-styleable> </resources>
其中属性rippleColor为水波动画的颜色,rippleAlpha为其透明度,rippleTime为动画持续时间,maskAlpha为触摸遮掩层的透明度。
2、自定义RippleView类继承RelativeLayout布局,也可以由需求所定继承于其它类,实现水波扩散效果主要的有两点:水波扩散的绘制和动画
1)水波的绘制其实就是绘制一个圆形
复制代码
1canvas.drawCircle(mDownX, mDownY, mRadius, mRipplePaint);
2)动画效果就是该圆形的绘制从小到大的过程,而该圆形到最大时的半径长度就是当前所在布局的对角线长度:
复制代码
1
2
3
4
5
6@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 获取最大半径 mMaxRadius = (float) Math.sqrt(w * w + h * h); }
动画效果用属性动画ObjectAnimator来实现(ObjectAnimator是android3.0后出现的)如下
复制代码
1
2
3mRippleAnim = ObjectAnimator.ofFloat(this, "radius", 0, mMaxRadius); mRippleAnim.setInterpolator(new AccelerateDecelerateInterpolator()); mRippleAnim.setDuration(mRippleTime);
其中的radius为自定义的属性,在动画执行时会回调对应的方法,只需要在该方法中更新圆形的半径就行了
复制代码
1
2
3
4public void setRadius(final float radius) { mRadius = radius; invalidate(); }
RippleView完整代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168public class RippleView extends RelativeLayout { private int mRippleColor;// 水波颜色 private float mMaskAlpha;// 遮掩透明度 private float mRippleAlpha;// 水波透明度 private int mRippleTime;// 水波动画时间 private ObjectAnimator mRippleAnim;// 显示水波动画 private float mRadius;// 当前的半径 private float mMaxRadius;// 水波最大半径 private float mDownX; // 记录手指按下的位置 private float mDownY; private boolean mIsMask; private boolean mIsAnimating;// 是否正在播放动画 private RectF mRect; private Path mPath; private Paint mMaskPaint; private Paint mRipplePaint; public RippleView(Context context) { this(context, null); } public RippleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RippleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); // 获取自定义属性 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RippleView); mRippleColor = ta.getColor(R.styleable.RippleView_rippleColor, mRippleColor); mMaskAlpha = ta.getFloat(R.styleable.RippleView_maskAlpha, mMaskAlpha); mRippleAlpha = ta.getFloat(R.styleable.RippleView_rippleAlpha, mRippleAlpha); mRippleTime = ta.getInt(R.styleable.RippleView_rippleTime, mRippleTime); ta.recycle(); initLast(); } // 初始化方法 private void init() { mRippleColor = Color.BLACK; mMaskAlpha = 0.4f; mRippleAlpha = 0.8f; mRippleTime = 800; mPath = new Path(); mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mRipplePaint = new Paint(Paint.ANTI_ALIAS_FLAG); } // 初始化 private void initLast() { mMaskPaint.setColor(mRippleColor); mRipplePaint.setColor(mRippleColor); mMaskPaint.setAlpha((int) (mMaskAlpha * 255)); mRipplePaint.setAlpha((int) (mRippleAlpha * 255)); } // 初始化动画 private void initAnim() { mRippleAnim = ObjectAnimator.ofFloat(this, "radius", 0, mMaxRadius); mRippleAnim.setInterpolator(new AccelerateDecelerateInterpolator()); mRippleAnim.setDuration(mRippleTime); mRippleAnim.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { mIsAnimating = true; } @Override public void onAnimationEnd(Animator animator) { setRadius(0); mIsMask = false; mIsAnimating = false; } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } }); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 获取最大半径 mMaxRadius = (float) Math.sqrt(w * w + h * h); // 获取该类布局范围 mRect = new RectF(0f, 0f, getMeasuredWidth() * 1.0f, getMeasuredHeight() * 1.0f); // 初始化动画 initAnim(); } @Override public boolean onTouchEvent(MotionEvent event) { // 按下事件 if (event.getAction() == MotionEvent.ACTION_DOWN) { mIsMask = true; invalidate(); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { invalidate(); } // 抬起事件 else if (event.getAction() == MotionEvent.ACTION_UP) { mDownX = event.getX(); mDownY = event.getY(); if (mIsAnimating) { mRippleAnim.cancel(); } boolean isInView = mRect.contains(mDownX, mDownY); if (isInView) { mRippleAnim.start(); } else { mIsMask = false; invalidate(); } } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制遮掩 if (mIsMask) { canvas.save(Canvas.CLIP_SAVE_FLAG); mPath.reset(); mPath.addRect(mRect, Path.Direction.CW); canvas.clipPath(mPath); canvas.drawRect(mRect, mMaskPaint); canvas.restore(); } // 绘制水波 canvas.save(Canvas.CLIP_SAVE_FLAG); mPath.reset(); mPath.addCircle(mDownX, mDownY, mRadius, Path.Direction.CW); canvas.clipPath(mPath); canvas.drawCircle(mDownX, mDownY, mRadius, mRipplePaint); canvas.restore(); } // 属性动画回调的方法 public void setRadius(final float radius) { mRadius = radius; invalidate(); } }
界面布局代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:ripple="http://schemas.android.com/apk/res/com.example.rippleview" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000" > <com.example.rippleview.RippleView android:layout_width="match_parent" android:layout_height="100dp" android:layout_centerInParent="true" android:background="#ffffff" android:clickable="true" ripple:rippleColor="#ababab" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="click me" android:textSize="18sp" /> </com.example.rippleview.RippleView> </RelativeLayout>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是过时小懒虫最近收集整理的关于Android 5.0 实现水波扩散效果的全部内容,更多相关Android内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复