Android實現(xiàn)水波紋效果實例代碼
效果圖

attrs.xml
自定義屬性
<declare-styleable name="RippleAnimationView">
<attr name="ripple_anim_color" format="color" />
<!-- 水波紋填充類型 -->
<attr name="ripple_anim_type" format="enum">
<enum name="fillRipple" value="0" />
<enum name="strokeRipple" value="1" />
</attr>
<!-- 水波紋的半徑 -->
<attr name="radius" format="integer" />
<!-- 水波紋邊框大小 -->
<attr name="stroeWidth" format="integer" />
</declare-styleable>
RippleAnimationView.java
管理水波紋屬性以及動畫狀態(tài)
public class RippleAnimationView extends RelativeLayout {
private Paint paint;
private int radius;
private int strokeWidth;
private int rippleColor;
private AnimatorSet animatorSet;
public RippleAnimationView(Context context) {
this(context, null);
}
public RippleAnimationView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RippleAnimationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
paint = new Paint();
paint.setAntiAlias(true);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RippleAnimationView);
// 水波紋填充類型
int rippleType = array.getInt(R.styleable.RippleAnimationView_ripple_anim_type, 0);
radius = array.getInteger(R.styleable.RippleAnimationView_radius, 54);
strokeWidth = array.getInteger(R.styleable.RippleAnimationView_stroeWidth, 2);
rippleColor = array.getColor(R.styleable.RippleAnimationView_ripple_anim_color, ContextCompat.getColor(context,
R.color.colorAccent));
array.recycle();
// 設置畫筆線寬
paint.setStrokeWidth(UIUtils.getInstance().getWidth(strokeWidth));
if (rippleType == 0) {
paint.setStyle(Paint.Style.FILL);
} else {
paint.setStyle(Paint.Style.STROKE);
}
paint.setColor(rippleColor);
LayoutParams params = new LayoutParams(
UIUtils.getInstance().getWidth(radius + strokeWidth),
UIUtils.getInstance().getWidth(radius + strokeWidth));
params.addRule(CENTER_IN_PARENT, TRUE);
// 縮放系數(shù)
float maxScale = UIUtils.getInstance().displayMetricsWidth / (2 * UIUtils.getInstance().getWidth(
radius + strokeWidth
));
// 延遲時間
int rippleDuration = 3500;
int singleDelay = rippleDuration / 4; // 時間間隔
// 動畫集合
List<Animator> animatorList = new ArrayList<>();
// 實例化水波紋view
for (int i = 0;i<4;i++){
RippleCircleView rippleCircleView = new RippleCircleView(this);
addView(rippleCircleView,params);
// 添加水波紋到集合
viewList.add(rippleCircleView);
// 初始化屬性動畫
// x
ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(rippleCircleView,"ScaleX",
1.0f,maxScale);
scaleXAnimator.setRepeatCount(ObjectAnimator.INFINITE);// 無限循環(huán)
scaleXAnimator.setRepeatMode(ObjectAnimator.RESTART);
scaleXAnimator.setStartDelay(i*singleDelay);
scaleXAnimator.setDuration(rippleDuration);
animatorList.add(scaleXAnimator);
// y
ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(rippleCircleView,"ScaleY",
1.0f,maxScale);
scaleYAnimator.setRepeatCount(ObjectAnimator.INFINITE);// 無限循環(huán)
scaleYAnimator.setRepeatMode(ObjectAnimator.RESTART);
scaleYAnimator.setStartDelay(i*singleDelay);
scaleYAnimator.setDuration(rippleDuration);
animatorList.add(scaleYAnimator);
// alpha
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rippleCircleView,"Alpha",
1.0f,0f);
alphaAnimator.setRepeatCount(ObjectAnimator.INFINITE);// 無限循環(huán)
alphaAnimator.setRepeatMode(ObjectAnimator.RESTART);
alphaAnimator.setStartDelay(i*singleDelay);
alphaAnimator.setDuration(rippleDuration);
animatorList.add(alphaAnimator);
}
animatorSet = new AnimatorSet();
animatorSet.setInterpolator(new AccelerateDecelerateInterpolator()); // 差值器:先加速,后減速
animatorSet.playTogether(animatorList);
}
private boolean animationRunning;
private List<RippleCircleView> viewList = new ArrayList<>();
/**
* 開啟動畫
*/
public void startRippleAnimation(){
if (!animationRunning){
for (RippleCircleView rippleCircleView: viewList) {
rippleCircleView.setVisibility(VISIBLE);
}
animatorSet.start();
animationRunning = true;
}
}
/**
* 結束動畫
*/
public void stopRippleAnimation(){
if (animationRunning){
// 逆序播放(從外向內(nèi)播放動畫)
Collections.reverse(viewList);
for (RippleCircleView rippleCircleView: viewList) {
rippleCircleView.setVisibility(INVISIBLE);
}
animatorSet.end();
animationRunning = false;
}
}
public int getStrokeWidth() {
return strokeWidth;
}
public Paint getPaint() {
return paint;
}
public boolean isAnimationRunning() {
return animationRunning;
}
}
RippleCircleView.java
繪制水波紋
public class RippleCircleView extends View {
private RippleAnimationView rippleAnimationView;
public RippleCircleView(RippleAnimationView rippleAnimationView) {
this(rippleAnimationView.getContext(),null);
this.rippleAnimationView = rippleAnimationView;
// 一開始隱藏
this.setVisibility(INVISIBLE);
}
public RippleCircleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public RippleCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
int radius = Math.min(getWidth(),getHeight()) / 2;
// 畫圓
canvas.drawCircle(radius,radius,radius - rippleAnimationView.getStrokeWidth(),
rippleAnimationView.getPaint());
}
}
使用水波紋動畫
<com.wangyi.course.lession4.RippleAnimationView 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:id="@+id/ripple_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:ripple_anim_color="#c0362e"
app:stroeWidth="18"
app:ripple_anim_type="strokeRipple"
app:radius="150">
<ImageView
android:id="@+id/iv_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_play"
/>
</com.wangyi.course.lession4.RippleAnimationView>
RippleAnimationView rippleAnimationView = findViewById(R.id.ripple_view);
findViewById(R.id.iv_play)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rippleAnimationView.isAnimationRunning()) {
rippleAnimationView.stopRippleAnimation();
} else {
rippleAnimationView.startRippleAnimation();
}
}
});
到此這篇關于Android實現(xiàn)水波紋效果實例代碼的文章就介紹到這了,更多相關Android水波紋效果內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android Studio 中運行 groovy 程序的方法圖文詳解
這篇文章主要介紹了Android Studio 中 運行 groovy 程序的方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
Android 安全加密:數(shù)字簽名和數(shù)字證書詳解
本文主要介紹Android 安全加密數(shù)字簽名和數(shù)字證書的資料,這里整理詳細的資料及數(shù)字簽名和數(shù)字證書應用詳解,有需要的小伙伴可以參考下2016-09-09
Android基于opencv實現(xiàn)多通道分離與合并
針對圖像多通道的分離與混合,OpenCV 4中提供了split()函數(shù)和merge()函數(shù)用于解決這些需求。本文講解一下Android如何調(diào)用這些函數(shù)實現(xiàn)多通道分離與合并2021-06-06
Android中的Dalvik和ART詳解及區(qū)別分析
小編通過這篇文章給大家整理了什么是Dalvik和ART,并進行了區(qū)別的分析,下面一起來看看。2016-07-07
Android中HorizontalScrollView使用方法詳解
這篇文章主要為大家詳細介紹了Android中HorizontalScrollView使用方法,感興趣的小伙伴們可以參考一下2016-05-05
Android 加載大圖、多圖和LruCache緩存詳細介紹
這篇文章主要介紹了Android 加載大圖、多圖和LruCache緩存詳細介紹的相關資料,需要的朋友可以參考下2016-10-10

