亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android自定義WaveProgressView實(shí)現(xiàn)水波紋加載需求

 更新時(shí)間:2017年09月09日 15:17:47   作者:amazing7  
這篇文章主要為大家詳細(xì)介紹了Android自定義WaveProgressView實(shí)現(xiàn)水波紋加載需求,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

先看效果圖:

這里寫圖片描述

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

  源碼地址

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" />

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

比如,這是一個(gè)圓

<?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設(shè)置一張圖片,比如:

這里寫圖片描述 

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

1.2 在代碼中

你可以選擇進(jìn)行如下設(shè)置:

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

2. 代碼實(shí)現(xiàn)

  這里實(shí)現(xiàn)主要用到的知識(shí)有 自定義view、PorterDuffXfermode和二階貝塞爾曲線,不太清楚的可以在我博客找找,都有的?!  ?
  首先自定義WaveProgressView繼承View,在構(gòu)造函數(shù)中獲取布局文件中設(shè)置的背景,同時(shí)設(shè)置一個(gè)畫波浪的畫筆和畫文字的畫筆?! ?/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);
 /**
 * 進(jìn)度畫筆
 */
 mTextPaint = new Paint();
 mTextPaint.setAntiAlias(true);
 mTextPaint.setTextAlign(Paint.Align.CENTER);
     //開始不斷自我繪制,讓波浪動(dòng)起來(lái)
 handler.sendEmptyMessageDelayed(INVALIDATE,100);
 }

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

 Paint paint = new Paint();
 paint.setAntiAlias(true);
 Bitmap finalBmp = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
 /**
 * 產(chǎn)生一個(gè)同樣大小的畫布
 */
 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);
 /**
 * 對(duì)圖片給進(jìn)行縮放
 */
 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);
 /**
 * 繪制進(jìn)度文字
 */
 canvas.drawText(currentText, width/2, height/2, mTextPaint);
 return finalBmp;

  這里的CurY是上次波浪中線的y軸坐標(biāo),CurMidY 是當(dāng)前的Y軸坐標(biāo),每次波浪上升的時(shí)候?yàn)榱瞬划a(chǎn)生卡頓效果,把這1/100的上升分為10次來(lái)繪制。
  distance是x軸的偏移量,為了使水波動(dòng)起來(lái),每次繪制時(shí)都要向左進(jìn)行一段偏移?!?/p>

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

  每次偏移距離為 半波寬度/波浪震動(dòng)速度,因?yàn)橐粋€(gè)波是4個(gè)半波寬度形成一個(gè)循環(huán),然后又回到最開始x位置開始循環(huán)位移。
  根據(jù)view的寬度計(jì)算出一共要繪制多少個(gè)波形出來(lái),同時(shí)多加一個(gè)波為了向左平移。

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;
 }

  每次繪制以波形的左邊點(diǎn)、波形的右邊點(diǎn)、view的左下角、view的右下角、形成一個(gè)圖片把它繪制到內(nèi)存中新建的和view同大小的canvas上?!?/p>

mPath.reset();
mPath.moveTo(0-distance,CurY);

mPath.lineTo(width,height);
mPath.lineTo(0,height);
mPath.close();
canvas.drawPath(mPath, mPathPaint);

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

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

最后把文字繪制上去,注意我們?cè)诔跏蓟性O(shè)置了畫筆,為了能通過(guò)代碼設(shè)置文字的顏色,要把設(shè)置文字畫筆顏色和大小放在onDraw方法中。

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

為了使波浪動(dòng)起來(lái),使用handler循環(huán)調(diào)用invalidate刷新界面。同時(shí)應(yīng)該在構(gòu)造函數(shù)打開handler循環(huán)。

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;
  }
 }
 };

最后就是一些相關(guān)屬性設(shè)置的函數(shù)。

 /**
 * @param currentProgress 當(dāng)前進(jìn)度
 * @param currentText 當(dāng)前顯示的進(jìn)度文字
 */
 public void setCurrent(int currentProgress,String currentText) {
 this.currentProgress = currentProgress;
 this.currentText = currentText;
 }

 /**
 * @param maxProgress 設(shè)置進(jìn)度條的最大值,默認(rèn)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 一個(gè)波峰的寬度
 */
 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;
 }

實(shí)現(xiàn)還是比較簡(jiǎn)單的,源碼和demo都在上面的地址中,如果有什么問(wèn)題可以給我留言,謝謝!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論