最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android自定義View控件實現(xiàn)多種水波紋漣漪擴散效果

 更新時間:2018年03月31日 11:30:07   作者:ZHU_文濤  
這篇文章主要給大家介紹了關(guān)于Android自定義View控件實現(xiàn)多種水波紋漣漪擴散效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

效果圖

實現(xiàn)思路

這個效果實現(xiàn)起來并不難,重要的是思路

此View滿足了多種水波紋漣漪擴散效果,這要求它能滿足很多的變化

根據(jù)上面的樣式,可以看出此View需要滿足以下變化

  • 圓圈從中心可循環(huán)向外擴散
  • 圓圈之間的擴散間距可以改變
  • 可控制擴散圓的漸變度
  • 圓圈可以是線條樣式或者實心樣式
  • 圓圈擴散的速度可以控制
  • 適配圓圈不同大小下的擴散效果

具體實現(xiàn)

創(chuàng)建自定義屬性

首先為View創(chuàng)建自定義的xml屬性

在工程的values目錄下新建attrs.xml文件

 <declare-styleable name="mRippleView">
 <attr name="cColor" format="color"/>
 <attr name="cSpeed" format="integer"/>
 <attr name="cDensity" format="integer"/>
 <attr name="cIsFill" format="boolean"/>
 <attr name="cIsAlpha" format="boolean"/>
 </declare-styleable>

各個屬性的作用如下

  • cColor:View控件的顏色
  • cSpeed:向外擴散的速度
  • cDensity:圓形波紋擴散的間距
  • cIsFill:是否開啟填充模式,true為實心圓
  • cIsAlpha:是否開啟漸變效果,true為開啟

創(chuàng)建自定義View控件

新建RippleView類繼承View類,重寫它的三個構(gòu)造方法,獲取用戶設(shè)置的屬性,同時指定默認值

 public RippleView(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 // 獲取用戶配置屬性
 TypedArray tya = context.obtainStyledAttributes(attrs, R.styleable.mRippleView);
 mColor = tya.getColor(R.styleable.mRippleView_cColor, Color.BLUE);
 mSpeed = tya.getInt(R.styleable.mRippleView_cSpeed, 1);
 mDensity = tya.getInt(R.styleable.mRippleView_cDensity, 10);
 mIsFill = tya.getBoolean(R.styleable.mRippleView_cIsFill, false);
 mIsAlpha = tya.getBoolean(R.styleable.mRippleView_cIsAlpha, false);
 tya.recycle();
 init();
 }

使用TypedArray讀取完自定義的屬性后一定要記得調(diào)用recycle方法釋放掉

重寫onMeasure

測量onMeasure,首先需要測量出View的寬和高,并指定View在wrap_content時的最小范圍,對于View繪制流程還不熟悉的同學,可以先去了解下具體的繪制流程

http://m.fzitv.net/article/118775.htm

重寫onMeasure方法,其中我們要考慮當View的寬高被指定為wrap_content時的情況,如果我們不對wrap_content的情況進行處理,那么當使用者指定View的寬高為wrap_content時將無法正常顯示出View

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 int myWidthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
 int myWidthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
 int myHeightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
 int myHeightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
 // 獲取寬
 if (myWidthSpecMode == MeasureSpec.EXACTLY) {
  // match_parent/精確值
  mWidth = myWidthSpecSize;
 } else {
  // wrap_content
  mWidth = DensityUtil.dip2px(mContext, 120);
 }

 // 獲取高
 if (myHeightSpecMode == MeasureSpec.EXACTLY) {
  // match_parent/精確值
  mHeight = myHeightSpecSize;
 } else {
  // wrap_content
  mHeight = DensityUtil.dip2px(mContext, 120);
 }
 // 設(shè)置該view的寬高
 setMeasuredDimension(mWidth, mHeight);
 }

MeasureSpec的狀態(tài)分為三種EXACTLY、AT_MOST、UNSPECIFIED,這里只要單獨指定非精確值EXACTLY之外的情況就好了

本文中使用到的DensityUtil類,是為了將dp轉(zhuǎn)換為px來使用,以便適配不同的屏幕顯示效果

 public static int dip2px(Context context, float dpValue) {
 final float scale = context.getResources().getDisplayMetrics().density;
 return (int) (dpValue * scale + 0.5f);
 }

重寫onDraw

設(shè)計的整體思路如下圖所示


先要實現(xiàn)圓形向外擴散的效果

  • 初始化第一個圓

這里的動畫效果本來是想使用ValueAnimator屬性動畫的數(shù)值發(fā)生器來實現(xiàn),但是我們這里有很多的計算需求,所以最后還是選擇使用算法來實現(xiàn),方便控制圓的一些參數(shù)

想要實現(xiàn)擴散的效果,這里思路是在每次更新View時動態(tài)改變圓的半徑,同時還需要給圓設(shè)置漸變度數(shù),所以決定用一個類來保存圓的狀態(tài),所有圓都存在一個List里

// 添加第一個圓圈
mRipples = new ArrayList<>();
Circle c = new Circle(0, 255);
mRipples.add(c);

傳入Circle類里的兩個參數(shù),第一個0表示圓的初始寬度,第二個255表示初始透明度

  • 添加新圓

要想實現(xiàn)不斷有圓向外擴散,就需要在第一個圓擴散到一定范圍時在圓心處再添加一個圓,這個的范圍可以由圓的半徑來控制,當List集合中最后一個圓的半徑增加到某個值mDensity時,新的圓就從圓心處創(chuàng)建出來

// 添加圓
if (mRipples.size() > 0) {
 // 控制第二個圓出來的間距
 if (mRipples.get(mRipples.size() - 1).width > DensityUtil.dip2px(mContext, mDensity)) {
 mRipples.add(new Circle(0, 255));
 }
}
  • 刪除List中多余的圓

List中的圓存儲的數(shù)量不宜過多,多了內(nèi)存消耗大,需要在當圓的半徑超過View的寬度時就刪掉這個圓

// 當圓超出View的寬度后刪除
if (c.width > mWidth / 2) {
 mRipples.remove(i);
}

我們也可以在外切正方形的頂點處刪除這個圓,需要用到勾股定律來計算擴散圓到外切正方形頂點的位置


如上圖所示,得出計算公式為

// 使用勾股定律求得一個外切正方形中心點離頂點的距離
sqrtNumber = (int) (Math.sqrt(mWidth * mWidth + mHeight * mHeight) / 2);

這樣就需要修改刪除圓的位置了

if (c.width > sprtNumber) {
 mRipples.remove(i);
}
  • 控制擴散圓的漸變度

當圓在向View的邊緣擴散時,漸變度數(shù)的改變需要動態(tài)來計算,漸變的計算算法要適配不同的圓寬度大小,我們知道透明度是0~255之間的,0表示完全透明,255表示百分百不透明,計算的時候就是需要將這個數(shù)值等份分配到圓的寬度里

這里要區(qū)分一點,對于圓來說,寬度是由圓心從0開始向外遞增,而漸變度數(shù)則是由圓心從255開始向外遞減,當圓與最外圍的正方形內(nèi)切時漸變度必須變?yōu)?,由此分析得知,公式如下

透明度 = 255 - 圓的寬度 * (255 / View寬度)

double alpha = 255 - c.width * (255 / ((double) mWidth / 2));
c.alpha = (int) alpha;

GitHub地址

https://github.com/zhuwentao2150/RippleView

總結(jié)

關(guān)于自定義View的總結(jié)部分在我的其它博客中已經(jīng)寫過蠻多了,有興趣的可以去看看

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Android使用lottie加載json動畫的示例代碼

    Android使用lottie加載json動畫的示例代碼

    本篇文章主要介紹了Android使用lottie加載json動畫的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Kotlin Flow常用封裝類StateFlow使用詳解

    Kotlin Flow常用封裝類StateFlow使用詳解

    這篇文章主要為大家介紹了Kotlin Flow常用封裝類StateFlow使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Android activity和view判斷滑動

    Android activity和view判斷滑動

    這篇文章主要介紹了Android activity和view判斷滑動的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Jetpack?Compose基礎(chǔ)組件之文字組件

    Jetpack?Compose基礎(chǔ)組件之文字組件

    這篇文章主要為大家介紹了Jetpack?Compose基礎(chǔ)組件之文字組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • 淺談Android AsyncTask內(nèi)存安全的一種使用方式

    淺談Android AsyncTask內(nèi)存安全的一種使用方式

    這篇文章主要介紹了淺談Android AsyncTask內(nèi)存安全的一種使用方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • Android Studio升級到3.0后遇到的坑

    Android Studio升級到3.0后遇到的坑

    自從谷歌發(fā)布Android Studio 3.0版本后,一直心向往之,終于抽時間做了下升級處理,現(xiàn)在把升級過程中遇到的一些問題以及解決方案分享給大家,希望對大家能給有事幫助
    2017-11-11
  • Android自定義View實現(xiàn)顏色選取器

    Android自定義View實現(xiàn)顏色選取器

    這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)顏色選取器 ,類似SeekBar的方式通過滑動選擇顏色,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 源碼詳解Android中View.post()用法

    源碼詳解Android中View.post()用法

    本文通過源碼給大家詳細分析了在Android中View.post()的用法以及經(jīng)常遇到的問題和解決辦法,一起來學習下。
    2017-12-12
  • Android 通過自定義view實現(xiàn)水波紋效果案例詳解

    Android 通過自定義view實現(xiàn)水波紋效果案例詳解

    這篇文章主要介紹了Android 通過自定義view實現(xiàn)水波紋效果案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 詳解Android中的MVP架構(gòu)分解和實現(xiàn)

    詳解Android中的MVP架構(gòu)分解和實現(xiàn)

    本篇文章主要介紹了詳解Android中的MVP架構(gòu)分解和實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02

最新評論

北海市| 防城港市| 衡阳县| 朝阳区| 栾城县| 枣阳市| 武夷山市| 平乐县| 栖霞市| 青河县| 香港 | 察隅县| 凤庆县| 吉安市| 磐石市| 柏乡县| 高碑店市| 茂名市| 杭锦后旗| 合山市| 通州市| 梅河口市| 呼图壁县| 丰顺县| 石棉县| 崇明县| 莱州市| 诸暨市| 宣汉县| 贡嘎县| 千阳县| 永川市| 静宁县| 页游| 扶绥县| 阳城县| 深泽县| 清流县| 新宾| 山东| 江口县|