Android自定义view实现圆的扩散效果

时间:2021-05-20

本文实例为大家分享了Android自定义View的实现水波纹,供大家参考,具体内容如下

一、实现效果

MainActivity.xml

<?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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <jt.com.animatorcirecle.myview.DiffuseView android:id="@+id/diffuseView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" app:diffuse_color="@color/colorAccent" app:diffuse_coreColor="@color/colorPrimaryDark" app:diffuse_coreImage="@android:drawable/ic_menu_search" app:diffuse_coreRadius="100" app:diffuse_maxWidth="300" app:diffuse_speed="5" app:diffuse_width="4"/> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始扩散"/> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="停止扩散"/></LinearLayout>

MainActivity中的点击事件

public class MainActivity extends AppCompatActivity { private Button button; private Button button2; private DiffuseView diffuseView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = findViewById(R.id.button); button2 = findViewById(R.id.button2); diffuseView = findViewById(R.id.diffuseView); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diffuseView.start(); } }); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diffuseView.stop(); } }); }}

自定义view类

public class DiffuseView extends View { /** 扩散圆圈颜色 */ private int mColor = getResources().getColor(R.color.colorAccent); /** 圆圈中心颜色 */ private int mCoreColor = getResources().getColor(R.color.colorPrimary); /** 中心圆半径 */ private float mCoreRadius = 150; /** 扩散圆宽度 */ private int mDiffuseWidth = 3; /** 最大宽度 */ private Integer mMaxWidth = 255; /** 扩散速度 */ private int mDiffuseSpeed = 5; /** 是否正在扩散中 */ private boolean mIsDiffuse = false; // 透明度集合 private List<Integer> mAlphas = new ArrayList<>(); // 扩散圆半径集合 private List<Integer> mWidths = new ArrayList<>(); private Paint mPaint; public DiffuseView(Context context) { this(context, null); } public DiffuseView(Context context, AttributeSet attrs) { this(context, attrs, -1); } public DiffuseView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DiffuseView, defStyleAttr, 0); mColor = a.getColor(R.styleable.DiffuseView_diffuse_color, mColor); mCoreColor = a.getColor(R.styleable.DiffuseView_diffuse_coreColor, mCoreColor); mCoreRadius = a.getFloat(R.styleable.DiffuseView_diffuse_coreRadius, mCoreRadius); mDiffuseWidth = a.getInt(R.styleable.DiffuseView_diffuse_width, mDiffuseWidth); mMaxWidth = a.getInt(R.styleable.DiffuseView_diffuse_maxWidth, mMaxWidth); mDiffuseSpeed = a.getInt(R.styleable.DiffuseView_diffuse_speed, mDiffuseSpeed); a.recycle(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mAlphas.add(255); mWidths.add(0); } @Override public void invalidate() { if(hasWindowFocus()){ super.invalidate(); } } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); if(hasWindowFocus){ invalidate(); } } @Override public void onDraw(Canvas canvas) { // 绘制扩散圆 mPaint.setColor(mColor); for (int i = 0; i < mAlphas.size(); i ++) { // 设置透明度 Integer alpha = mAlphas.get(i); mPaint.setAlpha(alpha); // 绘制扩散圆 Integer width = mWidths.get(i); canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius + width, mPaint); if(alpha > 0 && width < mMaxWidth){ mAlphas.set(i, alpha - mDiffuseSpeed > 0 ? alpha - mDiffuseSpeed : 1); mWidths.set(i, width + mDiffuseSpeed); } } // 判断当扩散圆扩散到指定宽度时添加新扩散圆 if (mWidths.get(mWidths.size() - 1) >= mMaxWidth / mDiffuseWidth) { mAlphas.add(255); mWidths.add(0); } // 超过10个扩散圆,删除最外层 if(mWidths.size() >= 10){ mWidths.remove(0); mAlphas.remove(0); } // 绘制中心圆 mPaint.setAlpha(255); mPaint.setColor(mCoreColor); canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius, mPaint); if(mIsDiffuse){ invalidate(); } } /** * 开始扩散 */ public void start() { mIsDiffuse = true; invalidate(); } /** * 停止扩散 */ public void stop() { mIsDiffuse = false; mWidths.clear(); mAlphas.clear(); mAlphas.add(255); mWidths.add(0); invalidate(); } /** * 是否扩散中 */ public boolean isDiffuse(){ return mIsDiffuse; } /** * 设置扩散圆颜色 */ public void setColor(int colorId){ mColor = colorId; } /** * 设置中心圆颜色 */ public void setCoreColor(int colorId){ mCoreColor = colorId; } /** * 设置中心圆半径 */ public void setCoreRadius(int radius){ mCoreRadius = radius; } /** * 设置扩散圆宽度(值越小宽度越大) */ public void setDiffuseWidth(int width){ mDiffuseWidth = width; } /** * 设置最大宽度 */ public void setMaxWidth(int maxWidth){ mMaxWidth = maxWidth; } /** * 设置扩散速度,值越大速度越快 */ public void setDiffuseSpeed(int speed){ mDiffuseSpeed = speed; }}

自己添加的attrs.xml(创建在Values包底下,切勿倒错)

<?xml version="1.0" encoding="utf-8"?><resources> <!--扩散圆颜色--> <attr name="diffuse_color" format="color"/> <!--中心圆颜色--> <attr name="diffuse_coreColor" format="color"/> <!--中心圆图片--> <attr name="diffuse_coreImage" format="reference"/> <!--中心圆半径--> <attr name="diffuse_coreRadius" format="float"/> <!--扩散圆宽度,值越小越宽--> <attr name="diffuse_width" format="integer"/> <!--最大扩散宽度--> <attr name="diffuse_maxWidth" format="integer"/> <!--扩散速度,值越大越快--> <attr name="diffuse_speed" format="integer"/> <declare-styleable name="DiffuseView"> <attr name="diffuse_color"/> <attr name="diffuse_coreColor"/> <attr name="diffuse_coreImage"/> <attr name="diffuse_coreRadius"/> <attr name="diffuse_width"/> <attr name="diffuse_maxWidth"/> <attr name="diffuse_speed"/> </declare-styleable></resources>

这样就搞定了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章