服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android自定义view实现圆的扩散效果

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

2022-09-22 16:23L.柚子皮 Android

这篇文章主要为大家详细介绍了Android自定义view实现圆的扩散效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

一、实现效果

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

MainActivity.xml

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?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中的点击事件

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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类

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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包底下,切勿倒错)

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?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>

这样就搞定了。

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

原文链接:https://blog.csdn.net/qq_43589739/article/details/86498562

延伸 · 阅读

精彩推荐