Android自定義View實現類似水波擴散效果
阿新 • • 發佈:2019-01-05
自定義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 voidinitPaints() { //畫筆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