Android自定義view實(shí)現(xiàn)圓的擴(kuò)散效果
本文實(shí)例為大家分享了Android自定義View的實(shí)現(xiàn)水波紋,供大家參考,具體內(nèi)容如下
一、實(shí)現(xiàn)效果

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="開始擴(kuò)散"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="停止擴(kuò)散"/>
</LinearLayout>
MainActivity中的點(diǎn)擊事件
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 {
/** 擴(kuò)散圓圈顏色 */
private int mColor = getResources().getColor(R.color.colorAccent);
/** 圓圈中心顏色 */
private int mCoreColor = getResources().getColor(R.color.colorPrimary);
/** 中心圓半徑 */
private float mCoreRadius = 150;
/** 擴(kuò)散圓寬度 */
private int mDiffuseWidth = 3;
/** 最大寬度 */
private Integer mMaxWidth = 255;
/** 擴(kuò)散速度 */
private int mDiffuseSpeed = 5;
/** 是否正在擴(kuò)散中 */
private boolean mIsDiffuse = false;
// 透明度集合
private List<Integer> mAlphas = new ArrayList<>();
// 擴(kuò)散圓半徑集合
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) {
// 繪制擴(kuò)散圓
mPaint.setColor(mColor);
for (int i = 0; i < mAlphas.size(); i ++) {
// 設(shè)置透明度
Integer alpha = mAlphas.get(i);
mPaint.setAlpha(alpha);
// 繪制擴(kuò)散圓
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);
}
}
// 判斷當(dāng)擴(kuò)散圓擴(kuò)散到指定寬度時(shí)添加新擴(kuò)散圓
if (mWidths.get(mWidths.size() - 1) >= mMaxWidth / mDiffuseWidth) {
mAlphas.add(255);
mWidths.add(0);
}
// 超過10個(gè)擴(kuò)散圓,刪除最外層
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();
}
}
/**
* 開始擴(kuò)散
*/
public void start() {
mIsDiffuse = true;
invalidate();
}
/**
* 停止擴(kuò)散
*/
public void stop() {
mIsDiffuse = false;
mWidths.clear();
mAlphas.clear();
mAlphas.add(255);
mWidths.add(0);
invalidate();
}
/**
* 是否擴(kuò)散中
*/
public boolean isDiffuse(){
return mIsDiffuse;
}
/**
* 設(shè)置擴(kuò)散圓顏色
*/
public void setColor(int colorId){
mColor = colorId;
}
/**
* 設(shè)置中心圓顏色
*/
public void setCoreColor(int colorId){
mCoreColor = colorId;
}
/**
* 設(shè)置中心圓半徑
*/
public void setCoreRadius(int radius){
mCoreRadius = radius;
}
/**
* 設(shè)置擴(kuò)散圓寬度(值越小寬度越大)
*/
public void setDiffuseWidth(int width){
mDiffuseWidth = width;
}
/**
* 設(shè)置最大寬度
*/
public void setMaxWidth(int maxWidth){
mMaxWidth = maxWidth;
}
/**
* 設(shè)置擴(kuò)散速度,值越大速度越快
*/
public void setDiffuseSpeed(int speed){
mDiffuseSpeed = speed;
}
}
自己添加的attrs.xml(創(chuàng)建在Values包底下,切勿倒錯(cuò))
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--擴(kuò)散圓顏色-->
<attr name="diffuse_color" format="color"/>
<!--中心圓顏色-->
<attr name="diffuse_coreColor" format="color"/>
<!--中心圓圖片-->
<attr name="diffuse_coreImage" format="reference"/>
<!--中心圓半徑-->
<attr name="diffuse_coreRadius" format="float"/>
<!--擴(kuò)散圓寬度,值越小越寬-->
<attr name="diffuse_width" format="integer"/>
<!--最大擴(kuò)散寬度-->
<attr name="diffuse_maxWidth" format="integer"/>
<!--擴(kuò)散速度,值越大越快-->
<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>
這樣就搞定了。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android Studio使用教程(四):Gradle基礎(chǔ)
這篇文章主要介紹了Android Studio使用教程(四):Gradle基礎(chǔ),本文講解了什么是Gradle、安裝Gradle、Gradle 基本概念等內(nèi)容,需要的朋友可以參考下2015-05-05
android輸入框與文本框加滾動(dòng)條scrollview示例
這篇文章主要介紹了android輸入框與文本框加滾動(dòng)條scrollview示例,需要的朋友可以參考下2014-05-05
Android實(shí)現(xiàn)視頻播放--騰訊瀏覽服務(wù)(TBS)功能
TBS視頻播放器可以支持市面上幾乎所有的視頻格式,包括mp4, flv, avi, 3gp, webm, ts, ogv, m3u8, asf, wmv, rm, rmvb, mov, mkv等18種視頻格式。這篇文章主要介紹了Android實(shí)現(xiàn)視頻播放--騰訊瀏覽服務(wù)(TBS),需要的朋友可以參考下2018-07-07
Android判斷是否有拍照權(quán)限的實(shí)例代碼
android在開發(fā)中有時(shí)候要判斷應(yīng)用中是否有某項(xiàng)權(quán)限,下面通過本文給大家分享Android判斷是否有拍照權(quán)限的實(shí)例代碼,需要的的朋友參考下吧2017-07-07
詳解Android的MVVM框架 - 數(shù)據(jù)綁定
這篇文章主要介紹了詳解Android的MVVM框架 - 數(shù)據(jù)綁定,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05
Android編程中context及全局變量實(shí)例詳解
這篇文章主要介紹了Android編程中context及全局變量的用法,結(jié)合實(shí)例形式較為詳細(xì)的分析講述了context及全局變量的使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2015-12-12
Android打造屬于自己的新聞平臺(tái)(客戶端+服務(wù)器)
這篇文章主要為大家詳細(xì)介紹了Android打造屬于自己的新聞平臺(tái)的相關(guān)資料,Android實(shí)現(xiàn)新聞客戶端服務(wù)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06

