介紹:水波紋散開效果的控件在 App 里面還是比較常見的,例如 網(wǎng)易云音樂歌曲識別,附近搜索場景。
創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比黔江網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式黔江網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋黔江地區(qū)。費用合理售后完善,10多年實體公司更值得信賴。
看下實現(xiàn)的效果:

實現(xiàn)思路: 先將最大圓半徑與最小圓半徑間距分成幾等份,從內(nèi)到外,Paint 透明度依次遞減,繪制出同心圓,然后不斷的改變這些同心圓的半徑大小,延遲一定時間重繪,便達到了想外散開的動畫效果了。
public class WaveView extends View {
private static final String TAG = "WaveView";
private int waveColor;
private int waveCount;
private Bitmap waveCenterIcon;
private Paint paint;
private int mWidth;
private int mHeight;
private int centerX;
private int centerY;
private float radius; // 最外圓半徑,即最大半徑
private float innerRadius; // 最內(nèi)圓的半徑,即最小半徑
private int centerIconWidth;
private int centerIconHeight;
private float[] waveDegreeArr;
private boolean isRunning = true;
public WaveView(Context context) {
this(context, null);
}
public WaveView(Context context, AttributeSet attrs) {
super(context, attrs);
readAttrs(context, attrs);
init();
}
private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(waveColor);
paint.setStyle(Paint.Style.FILL);
waveDegreeArr = new float[waveCount];
// 設(shè)置中間 drawable 點擊事件
}
private void readAttrs(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WaveView);
try {
waveColor = typedArray.getColor(R.styleable.WaveView_waveColor, 0xffff0000);
waveCount = typedArray.getInt(R.styleable.WaveView_waveCount, 4);
Drawable centerDrawable = typedArray.getDrawable(R.styleable.WaveView_waveCenterIcon);
waveCenterIcon = ((BitmapDrawable) centerDrawable).getBitmap();
} catch (Exception e) {
} finally {
typedArray.recycle();
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
centerX = mWidth / 2;
centerY = mHeight / 2;
radius = Math.min(mWidth, mHeight) / 2f;
centerIconWidth = waveCenterIcon.getWidth();
centerIconHeight = waveCenterIcon.getHeight();
innerRadius = Math.max(centerIconWidth, centerIconHeight) * 1.2f;
for (int i = 0; i < waveCount; i++) {
waveDegreeArr[i] = innerRadius + (radius - innerRadius) / waveCount * i;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(dp2Px(120), MeasureSpec.EXACTLY);
}
if (heightMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.AT_MOST) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(dp2Px(120), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
drawWave(canvas);
drawCenterCircle(canvas);
drawCenterIcon(canvas);
}
private void drawCenterCircle(Canvas canvas) {
canvas.drawCircle(centerX, centerY, innerRadius, paint);
}
private void drawWave(Canvas canvas) {
for (int i = 0; i < waveCount; i++) {
paint.setAlpha((int) (255 - 255 * waveDegreeArr[i] / radius));
canvas.drawCircle(centerX, centerY, waveDegreeArr[i], paint);
}
for (int i = 0; i < waveDegreeArr.length; i++) {
if ((waveDegreeArr[i] += 4) > radius) {
waveDegreeArr[i] = innerRadius;
}
}
if (isRunning) {
postInvalidateDelayed(50);
}
}
private void drawCenterIcon(Canvas canvas) {
paint.setAlpha(255);
int left = centerX - centerIconWidth / 2;
int top = centerY - centerIconHeight / 2;
canvas.drawBitmap(waveCenterIcon, left, top, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
// 處理事件邏輯
handleEvent(event);
return true;
}
return true;
}
private void handleEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
Log.i(TAG, "handleEvent: " + "(" + touchX + "," + touchY + ")");
float distanceX = Math.abs(touchX - centerX);
float distanceY = Math.abs(touchY - centerY);
// 計算觸摸點距離中心點的距離
float distance = (float) Math.sqrt(distanceX * distanceX + distanceY * distanceY);
// 當點擊的點距離中心點距離小于最內(nèi)圓半徑時,認為是點擊有效,否則無效
if (distance < innerRadius) {
if (listener != null) {
listener.onCenterWaveClick();
}
}
}
OnCenterWaveClickListener listener;
public interface OnCenterWaveClickListener {
void onCenterWaveClick();
}
public void setOnCenterWaveClickListener(OnCenterWaveClickListener listener) {
this.listener = listener;
}
public void toggle() {
isRunning = !isRunning;
invalidate();
}
public boolean isWaveRunning() {
return isRunning;
}
private int dp2Px(int dpValue) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, getResources().getDisplayMetrics());
}
}
github地址:https://github.com/xing16/WaveView
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
標題名稱:Android自定義View實現(xiàn)水波紋效果
URL鏈接:http://www.chinadenli.net/article42/ihoshc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機、ChatGPT、域名注冊、手機網(wǎng)站建設(shè)、營銷型網(wǎng)站建設(shè)、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)