一、效果
点击开始:
点击停止:
二、在MainActivity中
import android.graphics.Paint;import android.os.Bundle;import android.support.v4.view.animation.LinearOutSlowInInterpolator;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener {// private WaveView mWaveView1;private WaveView mWaveView2;private Button mStart;private Button mStop;private CircleImageView circleImageView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mStart = (Button) findViewById(R.id.start);mStop = (Button) findViewById(R.id.stop);circleImageView = (CircleImageView) findViewById(R.id.civ_info);circleImageView.setImageResource(R.mipmap.icon_ku);mWaveView2 = (WaveView) findViewById(R.id.wave_view2);mWaveView2.setDuration(5000);mWaveView2.setStyle(Paint.Style.FILL_AND_STROKE);mWaveView2.setColor(getResources().getColor(R.color.green));mWaveView2.setInterpolator(new LinearOutSlowInInterpolator());mStart.setOnClickListener(this);mStop.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.start:mWaveView2.setColor(getResources().getColor(R.color.green));mWaveView2.start();circleImageView.setImageResource(R.mipmap.icon_xiao);break;case R.id.stop:mWaveView2.setColor(getResources().getColor(R.color.red));mWaveView2.stop();circleImageView.setImageResource(R.mipmap.icon_ku);break;}}}
三、在activity_main中
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent" android:layout_height="match_parent"><Buttonandroid:id="@+id/start"android:layout_marginTop="10dp"android:layout_marginLeft="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="开始" /><Buttonandroid:id="@+id/stop"android:layout_toRightOf="@id/start"android:layout_marginTop="10dp"android:layout_marginLeft="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="停止" /><cn.hnshangyu.xiuyixiu.WaveViewandroid:id="@+id/wave_view2"android:layout_width="350dp"android:layout_height="350dp"android:layout_centerInParent="true"android:layout_marginTop="10dp"android:textSize="24dp" /><cn.hnshangyu.xiuyixiu.CircleImageViewandroid:id="@+id/civ_info"android:layout_width="100dp"android:layout_height="100dp"android:layout_centerInParent="true"android:gravity="center"android:src="@color/green"android:text="@string/app_name"android:textColor="@color/colorPrimary" />
四、在WaveView中:
import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;import android.view.animation.Interpolator;import android.view.animation.LinearInterpolator;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/*** 水波纹特效*/public class WaveView extends View {private float mInitialRadius=100; // 初始波纹半径private float mMaxRadiusRate = 0.85f; // 如果没有设置mMaxRadius,可mMaxRadius = 最小长度 * mMaxRadiusRate;private float mMaxRadius; // 最大波纹半径private long mDuration = 2000; // 一个波纹从创建到消失的持续时间private int mSpeed = 2000; // 波纹的创建速度,每2000ms创建一个private Interpolator mInterpolator = new LinearInterpolator();private List<Circle> mCircleList = new ArrayList<Circle>();private boolean mIsRunning;private boolean mMaxRadiusSet;private Paint mPaint;private long mLastCreateTime;private Runnable mCreateCircle = new Runnable() {@Overridepublic void run() {if (mIsRunning) {newCircle();postDelayed(mCreateCircle, mSpeed);}}};public WaveView(Context context) {this(context, null);}public WaveView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);setStyle(Paint.Style.FILL);}public void setStyle(Paint.Style style) {mPaint.setStyle(style);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {if (!mMaxRadiusSet) {mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f;}}public void setMaxRadiusRate(float maxRadiusRate) {this.mMaxRadiusRate = maxRadiusRate;}public void setColor(int color) {mPaint.setColor(color);}/*** 开始*/public void start() {if (!mIsRunning) {mIsRunning = true;mCreateCircle.run();}}/*** 停止*/public void stop() {mIsRunning = false;}protected void onDraw(Canvas canvas) {Iterator<Circle> iterator = mCircleList.iterator();while (iterator.hasNext()) {Circle circle = iterator.next();if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {mPaint.setAlpha(circle.getAlpha());canvas.drawCircle(getWidth() / 2, getHeight() / 2, circle.getCurrentRadius(), mPaint);} else {iterator.remove();}}if (mCircleList.size() > 0) {postInvalidateDelayed(10);}}public void setInitialRadius(float radius) {mInitialRadius = radius;}public void setDuration(long duration) {this.mDuration = duration;}public void setMaxRadius(float maxRadius) {this.mMaxRadius = maxRadius;mMaxRadiusSet = true;}public void setSpeed(int speed) {mSpeed = speed;}private void newCircle() {long currentTime = System.currentTimeMillis();if (currentTime - mLastCreateTime < mSpeed) {return;}Circle circle = new Circle();mCircleList.add(circle);invalidate();mLastCreateTime = currentTime;}private class Circle {private long mCreateTime;public Circle() {this.mCreateTime = System.currentTimeMillis();}public int getAlpha() {float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;return (int) ((1.0f - mInterpolator.getInterpolation(percent)) * 255);}public float getCurrentRadius() {float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius);}}public void setInterpolator(Interpolator interpolator) {mInterpolator = interpolator;if (mInterpolator == null) {mInterpolator = new LinearInterpolator();}}}
五、在CircleImageView中:
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ColorFilter;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.net.Uri;import android.support.annotation.ColorInt;import android.support.annotation.ColorRes;import android.support.annotation.DrawableRes;import android.util.AttributeSet;import android.widget.ImageView;public class CircleImageView extends ImageView {private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;private static final int COLORDRAWABLE_DIMENSION = 2;private static final int DEFAULT_BORDER_WIDTH = 0;private static final int DEFAULT_BORDER_COLOR = Color.BLACK;private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;private static final boolean DEFAULT_BORDER_OVERLAY = false;private final RectF mDrawableRect = new RectF();private final RectF mBorderRect = new RectF();private final Matrix mShaderMatrix = new Matrix();private final Paint mBitmapPaint = new Paint();private final Paint mBorderPaint = new Paint();private final Paint mFillPaint = new Paint();private int mBorderColor = DEFAULT_BORDER_COLOR;private int mBorderWidth = DEFAULT_BORDER_WIDTH;private int mFillColor = DEFAULT_FILL_COLOR;private Bitmap mBitmap;private BitmapShader mBitmapShader;private int mBitmapWidth;private int mBitmapHeight;private float mDrawableRadius;private float mBorderRadius;private ColorFilter mColorFilter;private boolean mReady;private boolean mSetupPending;private boolean mBorderOverlay;private boolean mDisableCircularTransformation;public CircleImageView(Context context) {super(context);init();}public CircleImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CircleImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);a.recycle();init();}private void init() {super.setScaleType(SCALE_TYPE);mReady = true;if (mSetupPending) {setup();mSetupPending = false;}}@Overridepublic ScaleType getScaleType() {return SCALE_TYPE;}@Overridepublic void setScaleType(ScaleType scaleType) {if (scaleType != SCALE_TYPE) {throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));}}@Overridepublic void setAdjustViewBounds(boolean adjustViewBounds) {if (adjustViewBounds) {throw new IllegalArgumentException("adjustViewBounds not supported.");}}@Overrideprotected void onDraw(Canvas canvas) {if (mDisableCircularTransformation) {super.onDraw(canvas);return;}if (mBitmap == null) {return;}if (mFillColor != Color.TRANSPARENT) {canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint);}canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);if (mBorderWidth > 0) {canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);}}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);setup();}@Overridepublic void setPadding(int left, int top, int right, int bottom) {super.setPadding(left, top, right, bottom);setup();}@Overridepublic void setPaddingRelative(int start, int top, int end, int bottom) {super.setPaddingRelative(start, top, end, bottom);setup();}public int getBorderColor() {return mBorderColor;}public void setBorderColor(@ColorInt int borderColor) {if (borderColor == mBorderColor) {return;}mBorderColor = borderColor;mBorderPaint.setColor(mBorderColor);invalidate();}/*** @deprecated Use {@link #setBorderColor(int)} instead*/@Deprecatedpublic void setBorderColorResource(@ColorRes int borderColorRes) {setBorderColor(getContext().getResources().getColor(borderColorRes));}/*** Return the color drawn behind the circle-shaped drawable.** @return The color drawn behind the drawable* @deprecated Fill color support is going to be removed in the future*/@Deprecatedpublic int getFillColor() {return mFillColor;}/*** Set a color to be drawn behind the circle-shaped drawable. Note that* this has no effect if the drawable is opaque or no drawable is set.** @param fillColor The color to be drawn behind the drawable* @deprecated Fill color support is going to be removed in the future*/@Deprecatedpublic void setFillColor(@ColorInt int fillColor) {if (fillColor == mFillColor) {return;}mFillColor = fillColor;mFillPaint.setColor(fillColor);invalidate();}/*** Set a color to be drawn behind the circle-shaped drawable. Note that* this has no effect if the drawable is opaque or no drawable is set.** @param fillColorRes The color resource to be resolved to a color and* drawn behind the drawable* @deprecated Fill color support is going to be removed in the future*/@Deprecatedpublic void setFillColorResource(@ColorRes int fillColorRes) {setFillColor(getContext().getResources().getColor(fillColorRes));}public int getBorderWidth() {return mBorderWidth;}public void setBorderWidth(int borderWidth) {if (borderWidth == mBorderWidth) {return;}mBorderWidth = borderWidth;setup();}public boolean isBorderOverlay() {return mBorderOverlay;}public void setBorderOverlay(boolean borderOverlay) {if (borderOverlay == mBorderOverlay) {return;}mBorderOverlay = borderOverlay;setup();}public boolean isDisableCircularTransformation() {return mDisableCircularTransformation;}public void setDisableCircularTransformation(boolean disableCircularTransformation) {if (mDisableCircularTransformation == disableCircularTransformation) {return;}mDisableCircularTransformation = disableCircularTransformation;initializeBitmap();}@Overridepublic void setImageBitmap(Bitmap bm) {super.setImageBitmap(bm);initializeBitmap();}@Overridepublic void setImageDrawable(Drawable drawable) {super.setImageDrawable(drawable);initializeBitmap();}@Overridepublic void setImageResource(@DrawableRes int resId) {super.setImageResource(resId);initializeBitmap();}@Overridepublic void setImageURI(Uri uri) {super.setImageURI(uri);initializeBitmap();}@Overridepublic void setColorFilter(ColorFilter cf) {if (cf == mColorFilter) {return;}mColorFilter = cf;applyColorFilter();invalidate();}@Overridepublic ColorFilter getColorFilter() {return mColorFilter;}private void applyColorFilter() {if (mBitmapPaint != null) {mBitmapPaint.setColorFilter(mColorFilter);}}private Bitmap getBitmapFromDrawable(Drawable drawable) {if (drawable == null) {return null;}if (drawable instanceof BitmapDrawable) {return ((BitmapDrawable) drawable).getBitmap();}try {Bitmap bitmap;if (drawable instanceof ColorDrawable) {bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);} else {bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);}Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());drawable.draw(canvas);return bitmap;} catch (Exception e) {e.printStackTrace();return null;}}private void initializeBitmap() {if (mDisableCircularTransformation) {mBitmap = null;} else {mBitmap = getBitmapFromDrawable(getDrawable());}setup();}private void setup() {if (!mReady) {mSetupPending = true;return;}if (getWidth() == 0 && getHeight() == 0) {return;}if (mBitmap == null) {invalidate();return;}mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);mBitmapPaint.setAntiAlias(true);mBitmapPaint.setShader(mBitmapShader);mBorderPaint.setStyle(Paint.Style.STROKE);mBorderPaint.setAntiAlias(true);mBorderPaint.setColor(mBorderColor);mBorderPaint.setStrokeWidth(mBorderWidth);mFillPaint.setStyle(Paint.Style.FILL);mFillPaint.setAntiAlias(true);mFillPaint.setColor(mFillColor);mBitmapHeight = mBitmap.getHeight();mBitmapWidth = mBitmap.getWidth();mBorderRect.set(calculateBounds());mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);mDrawableRect.set(mBorderRect);if (!mBorderOverlay && mBorderWidth > 0) {mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);}mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);applyColorFilter();updateShaderMatrix();invalidate();}private RectF calculateBounds() {int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();int sideLength = Math.min(availableWidth, availableHeight);float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;float top = getPaddingTop() + (availableHeight - sideLength) / 2f;return new RectF(left, top, left + sideLength, top + sideLength);}private void updateShaderMatrix() {float scale;float dx = 0;float dy = 0;mShaderMatrix.set(null);if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {scale = mDrawableRect.height() / (float) mBitmapHeight;dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;} else {scale = mDrawableRect.width() / (float) mBitmapWidth;dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;}mShaderMatrix.setScale(scale, scale);mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);mBitmapShader.setLocalMatrix(mShaderMatrix);}}
六、在attrs中
<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="CircleImageView"><attr name="civ_border_width" format="dimension" /><attr name="civ_border_color" format="color" /><attr name="civ_border_overlay" format="boolean" /><attr name="civ_fill_color" format="color" /></declare-styleable><declare-styleable name="RangeSeekbar"><attr name="seekbarHeight" format="dimension" /><attr name="textSize" format="dimension" /><attr name="spaceBetween" format="dimension" /><attr name="leftCursorBackground" format="reference" /><attr name="rightCursorBackground" format="reference" /><attr name="markTextArray" format="reference" /><attr name="textColorNormal" format="color" /><attr name="textColorSelected" format="color" /><attr name="seekbarColorNormal" format="color" /><attr name="seekbarColorSelected" format="color" /><attr name="autoMoveDuration" format="integer" /></declare-styleable></resources>
以上所述是小编给大家介绍的Android实现水波纹效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!
新闻热点
疑难解答