一、效果

点击开始:

点击停止:

二、在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;

@Override

protected 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);

}

@Override

public 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中

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/activity_main"

android:layout_width="match_parent"

android:layout_height="match_parent"

>

android:id="@+id/start"

android:layout_marginTop="10dp"

android:layout_marginLeft="10dp"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="开始" />

android: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="停止" />

android:id="@+id/wave_view2"

android:layout_width="350dp"

android:layout_height="350dp"

android:layout_centerInParent="true"

android:layout_marginTop="10dp"

android:textSize="24dp" />

android: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 mCircleList = new ArrayList();

private boolean mIsRunning;

private boolean mMaxRadiusSet;

private Paint mPaint;

private long mLastCreateTime;

private Runnable mCreateCircle = new Runnable() {

@Override

public 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);

}

@Override

protected 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 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;

}

}

@Override

public ScaleType getScaleType() {

return SCALE_TYPE;

}

@Override

public void setScaleType(ScaleType scaleType) {

if (scaleType != SCALE_TYPE) {

throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));

}

}

@Override

public void setAdjustViewBounds(boolean adjustViewBounds) {

if (adjustViewBounds) {

throw new IllegalArgumentException("adjustViewBounds not supported.");

}

}

@Override

protected 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);

}

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

setup();

}

@Override

public void setPadding(int left, int top, int right, int bottom) {

super.setPadding(left, top, right, bottom);

setup();

}

@Override

public 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

*/

@Deprecated

public 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

*/

@Deprecated

public 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

*/

@Deprecated

public 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

*/

@Deprecated

public 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();

}

@Override

public void setImageBitmap(Bitmap bm) {

super.setImageBitmap(bm);

initializeBitmap();

}

@Override

public void setImageDrawable(Drawable drawable) {

super.setImageDrawable(drawable);

initializeBitmap();

}

@Override

public void setImageResource(@DrawableRes int resId) {

super.setImageResource(resId);

initializeBitmap();

}

@Override

public void setImageURI(Uri uri) {

super.setImageURI(uri);

initializeBitmap();

}

@Override

public void setColorFilter(ColorFilter cf) {

if (cf == mColorFilter) {

return;

}

mColorFilter = cf;

applyColorFilter();

invalidate();

}

@Override

public 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中

以上所述是小编给大家介绍的Android实现水波纹效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

android波纹动画,Android实现水波纹效果相关推荐

  1. android水波纹点击动画,android 控件点击水波纹效果的几种方案

    目前我所知道的至少有三种可以实现点击水波纹的效果 第一种:安卓自带的方法 在安卓中有自带的一种属性,可以实现水波纹的效果,就是在所需要点击的控件属性加上如下代码: android:background ...

  2. android水波效果,android动态壁纸中的水波纹效果

    [实例简介] android动态壁纸中的水波纹效果,采用opengl中的shader实现 [实例截图] [核心代码] @Override public String getVertexShader() ...

  3. Android 之自定义view实现水波纹效果

    在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她: 在这样的关键时候,身子板就一定得硬了, ...

  4. Android S 指纹解锁后的水波纹动画

    记录一下bug 由于测试人员对比了R和S的行为,还有Google Pixel6的行为都没有指纹解锁后的蓝色水波纹动画,所以寻找了好久才发现在Android S的SystemUI上多了一个类-AuthR ...

  5. Android 特效之炫酷水波纹动画

    效果图 示例代码 1.初始化画笔 public WaveView(Context context, AttributeSet attrs) {super(context, attrs);mPath = ...

  6. android 炫酷特效,Android 特效之炫酷水波纹动画

    效果图 示例代码 1.初始化画笔 public WaveView(Context context, AttributeSet attrs) { super(context, attrs); mPath ...

  7. android 进度条_Android仿水波纹流球进度条控制器,实现高端大气的主流特效

    今天看到一个效果挺不错的,就模仿了下来,加上了一些自己想要的效果,感觉还不错的样子,所以就分享出来了,话不多说,上图 CircleView 这里主要是实现中心圆以及水波特效 package com.l ...

  8. vue 鼠标点击特效动画(css3动画),水波纹动画效果

    效果展示 思路要点 通过向数组 waves push操作插入水波纹相关数据,使用 vue v-for 动态更新 waves 生成水波纹数据 水波纹使用fixed定位通过点击事件的 clientX 和 ...

  9. android弹球动画,Android动画之自定义Evaluator实现弹球效果

    前言 今天给大家带来的是自定义Evaluator实现弹球效果,我们先给大家来个效果图. 下面我们介绍具体代码流程 1. 自定义Point类 public class Point { private i ...

  10. html移动端语音波纹,html5 +css3 点击后水波纹扩散效果 兼容移动端

    html5+ js +css3 点击后水波纹扩散效果 兼容移动端-幸凡学习网 }.center{text-align:center}.btn{position:relative;width:13em; ...

最新文章

  1. [转]如何解决:Android中 Error generating final archive: Debug Certificate expired on 10/09/18 16:30 的错误...
  2. 【转】Cvmat与IplImage的相互转换
  3. Spark交互式分析平台Apache Zeppelin的安装
  4. Azure IoT Edge on Windows 10 IoT Core
  5. 浅谈mtk平台手机通过gprs网络连接pc
  6. 模糊PID控制算法 之 C语言实现
  7. DNF私服搭建的利弊关系
  8. 数据处理-倾斜摄影OSGB合并根节点
  9. 浅谈Struts2拦截器的原理与实现
  10. 如何防止mysql删库_数据库如何防止程序员删库到跑路
  11. socket网络通信实现与优化
  12. Python int()使用小结
  13. 基于物联网的室内环境监测系统的背景描述
  14. Linux怎么安装ca证书,如何在CentOS上安装自定义CA证书?
  15. 【CXY】JAVA基础 之 异常追踪栈
  16. java实训题:随机点名器
  17. 大一学生接触人工智能的路程
  18. 电脑显示计算机资源不足 新用户无法登录,三招解决win10电脑提示资源不足的问题...
  19. 韦德高清图片壁纸下载
  20. keras+theano安装教程

热门文章

  1. 使用Fastlane编写Android自动打包脚本
  2. fastlane php,fastlane安装与初体验
  3. linux图片裁剪工具,linux中如何使用终端裁剪图片?
  4. linux下的etc文件夹
  5. 「整理了一些让人惊艳的古文情话」
  6. 基于VB2008的winsocket控件网络编程
  7. Taylor’s Formula - 泰勒公式
  8. mybatis <where> <choose>标签
  9. 2021-1-16-JavaGuide老哥的操作系统常见问题总结 自己按照理解,综合了王道考研的视频,对内容进行了修改,增加了内容,以便于自己理解。这份材料不是背的,而是让自己去理解的。
  10. mysql里any是什么_sql中any和all的区别?