Android 實現(xiàn)圓圈擴(kuò)散水波動畫效果兩種方法
兩種方式實現(xiàn)類似水波擴(kuò)散效果,先上圖為敬
- 自定義view實現(xiàn)
- 動畫實現(xiàn)

自定義view實現(xiàn)
思路分析:通過canvas畫圓,每次改變圓半徑和透明度,當(dāng)半徑達(dá)到一定程度,再次從中心開始繪圓,達(dá)到不同層級的效果,通過不斷繪制達(dá)到view擴(kuò)散效果
private Paint centerPaint; //中心圓paint private int radius = 100; //中心圓半徑 private Paint spreadPaint; //擴(kuò)散圓paint private float centerX;//圓心x private float centerY;//圓心y private int distance = 5; //每次圓遞增間距 private int maxRadius = 80; //最大圓半徑 private int delayMilliseconds = 33;//擴(kuò)散延遲間隔,越大擴(kuò)散越慢 private List<Integer> spreadRadius = new ArrayList<>();//擴(kuò)散圓層級數(shù),元素為擴(kuò)散的距離 private List<Integer> alphas = new ArrayList<>();//對應(yīng)每層圓的透明度
style文件里自定義屬性
<declare-styleable name="SpreadView"> <!--中心圓顏色--> <attr name="spread_center_color" format="color" /> <!--中心圓半徑--> <attr name="spread_radius" format="integer" /> <!--擴(kuò)散圓顏色--> <attr name="spread_spread_color" format="color" /> <!--擴(kuò)散間距--> <attr name="spread_distance" format="integer" /> <!--擴(kuò)散最大半徑--> <attr name="spread_max_radius" format="integer" /> <!--擴(kuò)散延遲間隔--> <attr name="spread_delay_milliseconds" format="integer" /> </declare-styleable>
初始化
public SpreadView(Context context) {
this(context, null, 0);
}
public SpreadView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SpreadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpreadView, defStyleAttr, 0);
radius = a.getInt(R.styleable.SpreadView_spread_radius, radius);
maxRadius = a.getInt(R.styleable.SpreadView_spread_max_radius, maxRadius);
int centerColor = a.getColor(R.styleable.SpreadView_spread_center_color, ContextCompat.getColor(context, R.color.colorAccent));
int spreadColor = a.getColor(R.styleable.SpreadView_spread_spread_color, ContextCompat.getColor(context, R.color.colorAccent));
distance = a.getInt(R.styleable.SpreadView_spread_distance, distance);
a.recycle();
centerPaint = new Paint();
centerPaint.setColor(centerColor);
centerPaint.setAntiAlias(true);
//最開始不透明且擴(kuò)散距離為0
alphas.add(255);
spreadRadius.add(0);
spreadPaint = new Paint();
spreadPaint.setAntiAlias(true);
spreadPaint.setAlpha(255);
spreadPaint.setColor(spreadColor);
}
確定圓心位置
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//圓心位置
centerX = w / 2;
centerY = h / 2;
}
自定義view的繪制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < spreadRadius.size(); i++) {
int alpha = alphas.get(i);
spreadPaint.setAlpha(alpha);
int width = spreadRadius.get(i);
//繪制擴(kuò)散的圓
canvas.drawCircle(centerX, centerY, radius + width, spreadPaint);
//每次擴(kuò)散圓半徑遞增,圓透明度遞減
if (alpha > 0 && width < 300) {
alpha = alpha - distance > 0 ? alpha - distance : 1;
alphas.set(i, alpha);
spreadRadius.set(i, width + distance);
}
}
//當(dāng)最外層擴(kuò)散圓半徑達(dá)到最大半徑時添加新擴(kuò)散圓
if (spreadRadius.get(spreadRadius.size() - 1) > maxRadius) {
spreadRadius.add(0);
alphas.add(255);
}
//超過8個擴(kuò)散圓,刪除最先繪制的圓,即最外層的圓
if (spreadRadius.size() >= 8) {
alphas.remove(0);
spreadRadius.remove(0);
}
//中間的圓
canvas.drawCircle(centerX, centerY, radius, centerPaint);
//TODO 可以在中間圓繪制文字或者圖片
//延遲更新,達(dá)到擴(kuò)散視覺差效果
postInvalidateDelayed(delayMilliseconds);
}
xml樣式
<com.airsaid.diffuseview.widget.SpreadView android:id="@+id/spreadView" android:layout_width="match_parent" android:layout_height="wrap_content" app:spread_center_color="@color/colorAccent" app:spread_delay_milliseconds="35" app:spread_distance="5" app:spread_max_radius="90" app:spread_radius="100" app:spread_spread_color="@color/colorAccent" />
效果圖

中心圓處可以自定義寫文字,畫圖片等等...
動畫實現(xiàn)
思路分析:通過動畫實現(xiàn),imageView不停做動畫縮放+漸變
最中心的imageView保持不變
中間一層imageView從原始放大到1.4倍,同時從不透明變?yōu)榘胪该?/p>
最外層的imageView從1.4倍放大到1.8倍,同時從半透明變?yōu)槿该?/p>
利用shape畫一個圓,作為動畫基礎(chǔ)視圖
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="65dp"/> <solid android:color="@color/colorAccent"/> </shape>
布局視圖
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--中心imageView-->
<ImageView
android:id="@+id/iv_wave"
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_gravity="center"
android:background="@drawable/shape_circle" />
<!--中間的imageView-->
<ImageView
android:id="@+id/iv_wave_1"
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_gravity="center"
android:background="@drawable/shape_circle" />
<!--最外層imageView-->
<ImageView
android:id="@+id/iv_wave_2"
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_gravity="center"
android:background="@drawable/shape_circle" />
</FrameLayout>
中間imageView的動畫
private void setAnim1() {
AnimationSet as = new AnimationSet(true);
//縮放動畫,以中心從原始放大到1.4倍
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.4f, 1.0f, 1.4f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
//漸變動畫
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.5f);
scaleAnimation.setDuration(800);
scaleAnimation.setRepeatCount(Animation.INFINITE);
alphaAnimation.setRepeatCount(Animation.INFINITE);
as.setDuration(800);
as.addAnimation(scaleAnimation);
as.addAnimation(alphaAnimation);
iv1.startAnimation(as);
}
最外層imageView的動畫
private void setAnim2() {
AnimationSet as = new AnimationSet(true);
//縮放動畫,以中心從1.4倍放大到1.8倍
ScaleAnimation scaleAnimation = new ScaleAnimation(1.4f, 1.8f, 1.4f, 1.8f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
//漸變動畫
AlphaAnimation alphaAnimation = new AlphaAnimation(0.5f, 0.1f);
scaleAnimation.setDuration(800);
scaleAnimation.setRepeatCount(Animation.INFINITE);
alphaAnimation.setRepeatCount(Animation.INFINITE);
as.setDuration(800);
as.addAnimation(scaleAnimation);
as.addAnimation(alphaAnimation);
iv2.startAnimation(as);
}
效果圖

相比較而言,自定義view的效果更好點,動畫實現(xiàn)起來更方便點。
兩種方式實現(xiàn)的擴(kuò)散效果介紹完畢,具體項目里還是要按需變動的。
總結(jié)
以上所述是小編給大家介紹的Android 實現(xiàn)圓圈擴(kuò)散水波動畫效果兩種方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- Android實現(xiàn)水波紋擴(kuò)散效果的實例代碼
- Android自定義View控件實現(xiàn)多種水波紋漣漪擴(kuò)散效果
- Android波紋擴(kuò)散效果之仿支付寶咻一咻功能實現(xiàn)波紋擴(kuò)散特效
- Android實現(xiàn)點擊Button產(chǎn)生水波紋效果
- Android特效之水波紋的實現(xiàn)
- Android項目實戰(zhàn)手把手教你畫圓形水波紋loadingview
- Android仿水波紋流量球進(jìn)度條控制器
- Android實現(xiàn)水波紋效果
- Android自定義View 實現(xiàn)水波紋動畫引導(dǎo)效果
- Android自定義view實現(xiàn)圓的擴(kuò)散效果
相關(guān)文章
Android構(gòu)建Material Design應(yīng)用詳解
這篇文章主要為大家詳細(xì)介紹了Android構(gòu)建Material Design應(yīng)用,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
Flutter學(xué)習(xí)之創(chuàng)建一個內(nèi)嵌的navigation詳解
我們在flutter中可以使用Navigator.push或者Navigator.pushNamed方法來向Navigator中添加不同的頁面,從而達(dá)到頁面調(diào)整的目的。本文就來聊聊如何創(chuàng)建一個內(nèi)嵌的navigation吧2023-03-03
Android應(yīng)用中圖片瀏覽時實現(xiàn)自動切換功能的方法詳解
這篇文章主要介紹了Android應(yīng)用中圖片瀏覽時實現(xiàn)自動切換功能的方法,文中還講解了一個觸摸大圖進(jìn)行圖片切換的深入功能,需要的朋友可以參考下2016-04-04
Flutter使用AnimationController實現(xiàn)控制動畫
這篇文章主要想帶大家來嘗試一下Flutter如何使用AnimationController實現(xiàn)一個拖拽圖片,然后返回原點的動畫,感興趣的可以了解一下2023-05-05
android studio 3.4配置Android -jni 開發(fā)基礎(chǔ)的教程詳解
這篇文章主要介紹了android studio 3.4配置Android -jni 開發(fā)基礎(chǔ),本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09
Android點擊Button實現(xiàn)切換點擊圖片效果的示例
今天小編就為大家分享一篇關(guān)于Android點擊Button實現(xiàn)切換點擊圖片效果的示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
Android沉浸式狀態(tài)欄微技巧(帶你真正理解沉浸式模式)
因為Android官方從來沒有給出過沉浸式狀態(tài)欄這樣的命名,只有沉浸式模式(Immersive Mode)這種說法.下面通過本文給大家介紹Android沉浸式狀態(tài)欄微技巧,需要的朋友參考下2016-12-12

