1. 程式人生 > >Android自定義View實現類似水波擴散效果

Android自定義View實現類似水波擴散效果

自定義View一共分為6步

第一步

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);
initPaints(); } private void initPaints() { } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); }

2.實現畫筆paint類

本文一共兩隻畫筆

private void 
initPaints() { //畫筆1: centerPaint = new Paint(); centerPaint.setColor(Color.YELLOW); centerPaint.setAntiAlias(true);//抗鋸齒效果 //最開始不透明且擴散距離為0 alphas.add(255); spreadRadius.add(0); //畫筆2: spreadPaint = new Paint(); spreadPaint.setAntiAlias(true); spreadPaint.setAlpha(255); spreadPaint.setColor(Color.RED);
}

3.覆寫onMeasure(…)方法

實現這個方法告訴了母容器如何放棄自定義View,可以通過提供的measureSpecs來決定你的View的高和寬,以下是一個正方形,確認它的寬和高是一樣的。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int w = MeasureSpec.getSize(widthMeasureSpec);
    int h = MeasureSpec.getSize(heightMeasureSpec);
    int size = Math.min(w, h);
setMeasuredDimension(size, size);
}

注意:

這個方法需要至少保證一個setMeasuredDimension(..)呼叫,否則會報IllegalStateException錯誤。

4.實現onSizeChanged(…)方法

這個方法是你獲取View現在的寬和高. 這裡我們計算的是中心和半徑

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

5.實現onDraw(…)方法

這個方法提供瞭如何繪製view,它提供的Canvas類可以進行繪製。

@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);
//繪製擴散的圓
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);
}

6.新增你的View

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
    <com.qinqu.spreadviewdemo.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" />
</LinearLayout>


demo:https://download.csdn.net/download/haoxuhong/10457408