国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義WaveProgressView實現水波紋加載需求

2019-10-22 18:28:11
字體:
來源:轉載
供稿:網友

先看效果圖:

Android,WaveProgressView,水波紋,加載需求

  你可以定義成你項目的logo圖片,可以設置水波顏色、波長、波寬、字體大小、顏色、進度條的最大值,當前進度值,還可以設置波紋震動的快慢。當設置一個進度不變的時候,打開時還有一個動畫填滿的效果(比如第二個流量顯示,這里圖片沒有截出這個效果)。

  源碼地址

1. 如何使用

1.1 在布局文件中

  添加自定義控件:

<cn.fanrunqi.waveprogressview.WaveProgressView android:id="@+id/waveProgressbar" android:background="@drawable/circle" <!--android:background="@drawable/bg_a"--> android:layout_width="130dp" android:layout_height="130dp" />

  說明,這里的android:background定義的是控件的形狀,比如上面的圓形和美女,你可用shape.xml定義形狀圖片。

比如,這是一個圓

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#DDDDDD"/> <size android:width="150dp" android:height="150dp"/></shape>

也可以直接給android:background設置一張圖片,比如:

Android,WaveProgressView,水波紋,加載需求 

這里注意透明像素,還有為了圖片縮放的時候不變形,建議背景(不管是圖片還是圖形)為正方形。

1.2 在代碼中

你可以選擇進行如下設置:

//設置當前進度值和當前顯示的文字waveProgressbar.setCurrent(int currentProgress,String currentText); // 77, "788M/1024M"//設置進度條的最大值waveProgressbar.setMaxProgress(int maxProgress);//設置顯示文字的大小和顏色waveProgressbar.setText(String mTextColor,int mTextSize);//"#FFFF00", 41//設置水波的顏色waveProgressbar.setWaveColor(String mWaveColor); //"#5b9ef4"//設置波浪的高度和波浪的寬度(均為一個波峰的大?。﹚aveProgressbar.setWave(float mWaveHight,float mWaveWidth);//設置波浪的上下震動的速度(這里注意值越大,震動的越?。﹚aveProgressbar.setmWaveSpeed(int mWaveSpeed);//The larger the value, the slower the vibration

2. 代碼實現

  這里實現主要用到的知識有 自定義view、PorterDuffXfermode和二階貝塞爾曲線,不太清楚的可以在我博客找找,都有的?!  ?br />   首先自定義WaveProgressView繼承View,在構造函數中獲取布局文件中設置的背景,同時設置一個畫波浪的畫筆和畫文字的畫筆?! ?/p>

private void Init() { /** * 獲得背景 */ if(null==getBackground()){ throw new IllegalArgumentException(String.format("background is null.")); }else{ backgroundBitmap = getBitmapFromDrawable(getBackground()); } /** * 波浪畫筆 */ mPath = new Path(); mPathPaint = new Paint(); mPathPaint.setAntiAlias(true); mPathPaint.setStyle(Paint.Style.FILL); /** * 進度畫筆 */ mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setTextAlign(Paint.Align.CENTER);     //開始不斷自我繪制,讓波浪動起來 handler.sendEmptyMessageDelayed(INVALIDATE,100); }

  復寫onDraw方法,先把波浪畫在畫布上,然后畫背景(給背景畫筆設置PorterDuff.Mode.DST_ATOP模式:取上層非交集部分與下層交集部分 )。當然也可以是PorterDuff.Mode.SRC_ATOP,主要取決于你畫的先后順序。最后把文字畫上去,形成一個最終Bitmap,最后把這個Bitmap畫到onDraw的參數canvas上。

 Paint paint = new Paint(); paint.setAntiAlias(true); Bitmap finalBmp = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); /** * 產生一個同樣大小的畫布 */ Canvas canvas = new Canvas(finalBmp); /** * 繪制波浪 */ float CurMidY = height*(maxProgress-currentProgress)/maxProgress; if(CurY>CurMidY){ CurY = CurY - (CurY-CurMidY)/10; } mPath.reset(); mPath.moveTo(0-distance,CurY); int waveNum = width/((int)mWaveHalfWidth*4)+1; int multiplier = 0; for(int i =0;i<waveNum;i++){ mPath.quadTo(mWaveHalfWidth*(multiplier+1)-distance,CurY-mWaveHight,mWaveHalfWidth*(multiplier+2)-distance,CurY); mPath.quadTo(mWaveHalfWidth*(multiplier+3)-distance,CurY+mWaveHight,mWaveHalfWidth*(multiplier+4)-distance,CurY); multiplier+=4; } distance +=mWaveHalfWidth/mWaveSpeed; distance = distance%(mWaveHalfWidth*4); mPath.lineTo(width,height); mPath.lineTo(0,height); mPath.close(); canvas.drawPath(mPath, mPathPaint); /** * 對圖片給進行縮放 */ int min = Math.min(width,height); backgroundBitmap = Bitmap.createScaledBitmap(backgroundBitmap,min,min,false); /** * 使用DST_ATOP,取上層非交集部分與下層交集部分 。 */ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)); /** * 繪制圖片 */ canvas.drawBitmap(backgroundBitmap,0,0,paint); /** * 繪制進度文字 */ canvas.drawText(currentText, width/2, height/2, mTextPaint); return finalBmp;

  這里的CurY是上次波浪中線的y軸坐標,CurMidY 是當前的Y軸坐標,每次波浪上升的時候為了不產生卡頓效果,把這1/100的上升分為10次來繪制。
  distance是x軸的偏移量,為了使水波動起來,每次繪制時都要向左進行一段偏移?!?/p>

distance +=mWaveHalfWidth/mWaveSpeed;distance = distance%(mWaveHalfWidth*4);

  每次偏移距離為 半波寬度/波浪震動速度,因為一個波是4個半波寬度形成一個循環,然后又回到最開始x位置開始循環位移。
  根據view的寬度計算出一共要繪制多少個波形出來,同時多加一個波為了向左平移。

int waveNum = width/((int)mWaveHalfWidth*4)+1; int multiplier = 0; for(int i =0;i<waveNum;i++){  mPath.quadTo(mWaveHalfWidth*(multiplier+1)-distance,CurY-mWaveHight,mWaveHalfWidth*(multiplier+2)-distance,CurY);  mPath.quadTo(mWaveHalfWidth*(multiplier+3)-distance,CurY+mWaveHight,mWaveHalfWidth*(multiplier+4)-distance,CurY);  multiplier+=4; }

  每次繪制以波形的左邊點、波形的右邊點、view的左下角、view的右下角、形成一個圖片把它繪制到內存中新建的和view同大小的canvas上。 

mPath.reset();mPath.moveTo(0-distance,CurY);mPath.lineTo(width,height);mPath.lineTo(0,height);mPath.close();canvas.drawPath(mPath, mPathPaint);

  先對背景圖形進行縮放再繪制到canvas上,這里的縮放是按最小邊進行縮放。

int min = Math.min(width,height);backgroundBitmap = Bitmap.createScaledBitmap(backgroundBitmap,min,min,false);

最后把文字繪制上去,注意我們在初始化中設置了畫筆,為了能通過代碼設置文字的顏色,要把設置文字畫筆顏色和大小放在onDraw方法中。

mPathPaint.setColor(Color.parseColor(mWaveColor));mTextPaint.setColor(Color.parseColor(mTextColor));mTextPaint.setTextSize(mTextSize);canvas.drawText(currentText, width/2, height/2, mTextPaint);

為了使波浪動起來,使用handler循環調用invalidate刷新界面。同時應該在構造函數打開handler循環。

private static final int INVALIDATE = 0X777; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) {  super.handleMessage(msg);  switch (msg.what) {  case INVALIDATE:   invalidate();   sendEmptyMessageDelayed(INVALIDATE,RefreshGap);   break;  } } };

最后就是一些相關屬性設置的函數。

 /** * @param currentProgress 當前進度 * @param currentText 當前顯示的進度文字 */ public void setCurrent(int currentProgress,String currentText) { this.currentProgress = currentProgress; this.currentText = currentText; } /** * @param maxProgress 設置進度條的最大值,默認100 */ public void setMaxProgress(int maxProgress){ this.maxProgress = maxProgress; } /** * @param mTextColor 文字的顏色 * @param mTextSize 文字的大小 */ public void setText(String mTextColor,int mTextSize){ this.mTextColor = mTextColor; this.mTextSize = mTextSize; } /** * @param mWaveHight 波峰的高度 * @param mWaveWidth 一個波峰的寬度 */ public void setWave(float mWaveHight,float mWaveWidth){ this.mWaveHight = mWaveHight; this.mWaveHalfWidth = mWaveWidth/2; } /** * @param mWaveColor 水的顏色 */ public void setWaveColor(String mWaveColor){ this.mWaveColor = mWaveColor; } /** * 值越大震蕩的越慢 * @param mWaveSpeed */ public void setmWaveSpeed(int mWaveSpeed){ this.mWaveSpeed = mWaveSpeed; }

實現還是比較簡單的,源碼和demo都在上面的地址中,如果有什么問題可以給我留言,謝謝!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 农安县| 柳林县| 德江县| 文山县| 佳木斯市| 南陵县| 崇州市| 屏南县| 报价| 长子县| 呼图壁县| 江源县| 哈密市| 伊金霍洛旗| 年辖:市辖区| 南木林县| 崇明县| 桂东县| 中山市| 思茅市| 安康市| 乳山市| 都江堰市| 庄河市| 大庆市| 五常市| 胶州市| 武乡县| 萝北县| 长丰县| 舒城县| 交口县| 大理市| 杨浦区| 资中县| 贞丰县| 家居| 静海县| 大田县| 靖宇县| 米泉市|