Android 兩種方式實作類別似水波擴散效果

來源:互聯網
上載者:User

標籤:change   int   type   parent   get   rem   放大   odi   最大   

原文連結 https://mp.weixin.qq.com/s/M19tp_ShOO6esKdozi7Nlg

兩種方式實作類別似水波擴散效果,先為敬

  1. 自訂view實現
  2. 動畫實現

自訂view實現

思路分析:通過canvas畫圓,每次改變圓半徑和透明度,當半徑達到一定程度,再次從中心開始繪圓,達到不同層級的效果,通過不斷繪製達到view擴散效果

private Paint centerPaint; //中心圓paintprivate int radius = 100; //中心圓半徑private Paint spreadPaint; //擴散圓paintprivate float centerX;//圓心xprivate float centerY;//圓心yprivate int distance = 5; //每次圓遞增間距private int maxRadius = 80; //最大圓半徑private int delayMilliseconds = 33;//擴散延遲間隔,越大擴散越慢private List<Integer> spreadRadius = new ArrayList<>();//擴散圓層級數,元素為擴散的距離private List<Integer> alphas = new ArrayList<>();//對應每層圓的透明度

style檔案裡自訂屬性

<declare-styleable name="SpreadView">    <!--中心圓顏色-->    <attr name="spread_center_color" format="color" />    <!--中心圓半徑-->    <attr name="spread_radius" format="integer" />    <!--擴散圓顏色-->    <attr name="spread_spread_color" format="color" />    <!--擴散間距-->    <attr name="spread_distance" format="integer" />    <!--擴散最大半徑-->    <attr name="spread_max_radius" format="integer" />    <!--擴散延遲間隔-->    <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);    //最開始不透明且擴散距離為0    alphas.add(255);    spreadRadius.add(0);    spreadPaint = new Paint();    spreadPaint.setAntiAlias(true);    spreadPaint.setAlpha(255);    spreadPaint.setColor(spreadColor);}

確定圓心位置

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    //圓心位置    centerX = w / 2;    centerY = h / 2;}

自訂view的繪製

@Overrideprotected 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);        //繪製擴散的圓        canvas.drawCircle(centerX, centerY, radius + width, spreadPaint);        //每次擴散圓半徑遞增,圓透明度遞減        if (alpha > 0 && width < 300) {            alpha = alpha - distance > 0 ? alpha - distance : 1;            alphas.set(i, alpha);            spreadRadius.set(i, width + distance);        }    }    //當最外層擴散圓半徑達到最大半徑時添加新擴散圓    if (spreadRadius.get(spreadRadius.size() - 1) > maxRadius) {        spreadRadius.add(0);        alphas.add(255);    }    //超過8個擴散圓,刪除最先繪製的圓,即最外層的圓    if (spreadRadius.size() >= 8) {        alphas.remove(0);        spreadRadius.remove(0);    }    //中間的圓    canvas.drawCircle(centerX, centerY, radius, centerPaint);    //TODO 可以在中間圓繪製文字或者圖片    //延遲更新,達到擴散視覺差效果    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" />


中心圓處可以自訂寫文字,畫圖片等等...

動畫實現

思路分析:通過動畫實現,imageView不停做動畫縮放+漸層
最中心的imageView保持不變
中間一層imageView從原始放大到1.4倍,同時從不透明變為半透明
最外層的imageView從1.4倍放大到1.8倍,同時從半透明變為全透明
利用shape畫一個圓,作為動畫基礎視圖

<?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的效果更好點,動畫實現起來更方便點。

兩種方式實現的擴散效果介紹完畢,具體項目裡還是要按需變動的。

歡迎關注我的部落格:https://blog.manjiexiang.cn/
同時歡迎關注公眾號

Android 兩種方式實作類別似水波擴散效果

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.