欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義View之酷炫圓環(huán)(二)

 更新時間:2016年01月11日 10:27:44   作者:hellsam  
這篇文章主要介紹了Android自定義View之酷炫圓環(huán),本文是第二篇針對Android圓環(huán)實現(xiàn)方法進行的詳細闡述,感興趣的小伙伴們可以參考一下

先看下最終的效果
靜態(tài):


動態(tài):


一、開始實現(xiàn)
新建一個DoughnutProgress繼承View

  public class DoughnutProgress extends View {

  }

先給出一些常量、變量以及公共方法的代碼,方便理解后面的代碼
   

private static final int DEFAULT_MIN_WIDTH = 400; //View默認最小寬度
  private static final int RED = 230, GREEN = 85, BLUE = 35; //基礎(chǔ)顏色,這里是橙紅色
  private static final int MIN_ALPHA = 30; //最小不透明度
  private static final int MAX_ALPHA = 255; //最大不透明度
  private static final float doughnutRaduisPercent = 0.65f; //圓環(huán)外圓半徑占View最大半徑的百分比
  private static final float doughnutWidthPercent = 0.12f; //圓環(huán)寬度占View最大半徑的百分比
  private static final float MIDDLE_WAVE_RADUIS_PERCENT = 0.9f; //第二個圓出現(xiàn)時,第一個圓的半徑百分比
  private static final float WAVE_WIDTH = 5f; //波紋圓環(huán)寬度

  //圓環(huán)顏色
  private static int[] doughnutColors = new int[]{
      Color.argb(MAX_ALPHA, RED, GREEN, BLUE),
      Color.argb(MIN_ALPHA, RED, GREEN, BLUE),
      Color.argb(MIN_ALPHA, RED, GREEN, BLUE)};

  private Paint paint = new Paint(); //畫筆
  private float width; //自定義view的寬度
  private float height; //自定義view的高度
  private float currentAngle = 0f; //當前旋轉(zhuǎn)角度
  private float raduis; //自定義view的最大半徑
  private float firstWaveRaduis;
  private float secondWaveRaduis;

  //
  private void resetParams() {
    width = getWidth();
    height = getHeight();
    raduis = Math.min(width, height)/2;
  }

  private void initPaint() {
    paint.reset();
    paint.setAntiAlias(true);
  }

重寫onMeasure方法,為什么要重寫onMeasure方法可以看我的上一篇文章,點這里

  /**
   * 當布局為wrap_content時設(shè)置默認長寬
   *
   * @param widthMeasureSpec
   * @param heightMeasureSpec
   */
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));
  }

  private int measure(int origin) {
    int result = DEFAULT_MIN_WIDTH;
    int specMode = MeasureSpec.getMode(origin);
    int specSize = MeasureSpec.getSize(origin);
    if (specMode == MeasureSpec.EXACTLY) {
      result = specSize;
    } else {
      if (specMode == MeasureSpec.AT_MOST) {
        result = Math.min(result, specSize);
      }
    }
    return result;
  }

下面就是最重要的重寫onDraw方法,大致流程如下
在開始繪制之前,先初始化width、height、raduis, 以及將View的中心作為原點

  resetParams();

  //將畫布中心設(shè)為原點(0,0), 方便后面計算坐標
  canvas.translate(width / 2, height / 2);

實現(xiàn)靜態(tài)的漸變圓環(huán)
1、畫漸變圓環(huán)

  float doughnutWidth = raduis * doughnutWidthPercent;//圓環(huán)寬度
   //圓環(huán)外接矩形
   RectF rectF = new RectF(
   -raduis * doughnutRaduisPercent, 
   -raduis * doughnutRaduisPercent, 
   raduis * doughnutRaduisPercent, 
   raduis * doughnutRaduisPercent);
   initPaint();
   paint.setStrokeWidth(doughnutWidth);
   paint.setStyle(Paint.Style.STROKE);
   paint.setShader(new SweepGradient(0, 0, doughnutColors, null));
   canvas.drawArc(rectF, 0, 360, false, paint);

通過修改doughnutColors可以實現(xiàn)不同的漸變效果
2、畫圓環(huán)旋轉(zhuǎn)頭部的圓

  //畫旋轉(zhuǎn)頭部圓
   initPaint();
   paint.setStyle(Paint.Style.FILL);
   paint.setColor(Color.argb(MAX_ALPHA, RED, GREEN, BLUE));
   canvas.drawCircle(raduis * doughnutRaduisPercent, 0, doughnutWidth / 2, paint);

此時運行代碼得到效果如下圖:


我們還可以在繪制圓環(huán)之前通過旋轉(zhuǎn)畫布得到不同初始狀態(tài)
    canvas.rotate(-45, 0, 0);

    canvas.rotate(-180, 0, 0);

此時聰明的你應該已經(jīng)想到怎么讓這個圓環(huán)旋轉(zhuǎn)起來了吧^_^

對!正如你所想的,就是通過canvas.rotate方法不停地旋轉(zhuǎn)畫布(這個“地”是這么用的吧o(╯□╰)o)

讓圓環(huán)旋轉(zhuǎn)起來
在繪制圓環(huán)之前加上下面的代碼:

  //轉(zhuǎn)起來
  canvas.rotate(-currentAngle, 0, 0);
  if (currentAngle >= 360f){
    currentAngle = currentAngle - 360f;
  } else{
    currentAngle = currentAngle + 2f;
  }

然后再讓一個線程循環(huán)刷新就好了

private Thread thread = new Thread(){
  @Override
  public void run() {
    while(true){
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      postInvalidate();
    }
  }
};

試試!轉(zhuǎn)起來了嗎O(∩_∩)O~

下面是比較有意思的部分,實現(xiàn)類似水波漣漪的效果
分析水波漣漪效果的實現(xiàn)原理(畫了張草圖方便理解):


假設(shè)淡黃色背景區(qū)域為整個View的大小

黑色圓圈為View內(nèi)的最大圓(半徑為R3)

橙色圓環(huán)代表漸變圓環(huán)

紅色圓圈代表圓環(huán)的外圓(半徑為R1)

紫色圓圈是干啥子的,待會兒再介紹~(半徑為R2)

通過觀察實現(xiàn)的最終效果,可以發(fā)現(xiàn)有個圓的半徑從R1逐漸增大R3,不透明度逐漸減小到0。

那是不是這樣周而復始就可以實現(xiàn)最終的效果了呢?

沒那么簡單。。。

仔細觀察發(fā)現(xiàn),第二個圓不是等到第一個圓的半徑增大到R3才開始出現(xiàn)的,而是在將要消失的時候就出現(xiàn)了,有一段時間是兩個圓同時存在的。

那么我們就假設(shè)當?shù)谝粋€圓的半徑增大到R2,第二個圓開始出現(xiàn)。

開始想象兩個圓的循環(huán)運行模型~~~

我的方案是:

繪制兩個圓,每個圓的半徑都從R1增大到R1+2x(R2-R1),不透明度還是從R1到R3的過程中逐漸變?yōu)?,也就是當圓的半徑大于R3時,不透明度就為0了(不可見了),將第一個圓半徑初始值設(shè)為R1,第二個圓半徑初始值設(shè)為R2。這樣兩個圓半徑同時逐漸增大,當半徑大于 R1+2x(R2-R1)時又重新回到R1大小繼續(xù)增大,就實現(xiàn)了類似水波漣漪的效果了。

  //實現(xiàn)類似水波漣漪效果
  initPaint();
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(5);
  secondWaveRaduis = calculateWaveRaduis(secondWaveRaduis);
  firstWaveRaduis = calculateWaveRaduis(secondWaveRaduis + raduis*(MIDDLE_WAVE_RADUIS_PERCENT - doughnutRaduisPercent) - raduis*doughnutWidthPercent/2);
  paint.setColor(Color.argb(calculateWaveAlpha(secondWaveRaduis), RED, GREEN, BLUE));
  canvas.drawCircle(0, 0, secondWaveRaduis, paint); //畫第二個圓(初始半徑較小的)

  initPaint();
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(5);
  paint.setColor(Color.argb(calculateWaveAlpha(firstWaveRaduis), RED, GREEN, BLUE));
  canvas.drawCircle(0, 0, firstWaveRaduis, paint); //畫第一個圓(初始半徑較大的)


  /**
   * 計算波紋圓的半徑
   * @param waveRaduis
   * @return
   */
  private float calculateWaveRaduis(float waveRaduis){
    if(waveRaduis < raduis*doughnutRaduisPercent + raduis*doughnutWidthPercent/2){
      waveRaduis = raduis*doughnutRaduisPercent + raduis*doughnutWidthPercent/2;
    }
    if(waveRaduis > raduis*MIDDLE_WAVE_RADUIS_PERCENT + raduis*(MIDDLE_WAVE_RADUIS_PERCENT - doughnutRaduisPercent) - raduis*doughnutWidthPercent/2){
      waveRaduis = waveRaduis - (raduis*MIDDLE_WAVE_RADUIS_PERCENT + raduis*(MIDDLE_WAVE_RADUIS_PERCENT - doughnutRaduisPercent) - raduis*doughnutWidthPercent/2) + raduis*doughnutWidthPercent/2 + raduis*doughnutRaduisPercent;
    }
      waveRaduis += 0.6f;
    return waveRaduis;
  }

  /**
   * 根據(jù)波紋圓的半徑計算不透明度
   * @param waveRaduis
   * @return
   */
  private int calculateWaveAlpha(float waveRaduis){
    float percent = (waveRaduis-raduis*doughnutRaduisPercent-raduis*doughnutWidthPercent/2)/(raduis-raduis*doughnutRaduisPercent-raduis*doughnutWidthPercent/2);
    if(percent >= 1f){
      return 0;
    }else{
      return (int) (MIN_ALPHA*(1f-percent));
    }
  }

以上就是本文的全部內(nèi)容,希望對大家的學習Android軟件編程有所幫助。

相關(guān)文章

  • Android 靜默安裝和卸載的方法

    Android 靜默安裝和卸載的方法

    本篇文章主要介紹了Android 靜默安裝和卸載的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Android 百度地圖POI搜索功能實例代碼

    Android 百度地圖POI搜索功能實例代碼

    POI(Point of Interest),中文可以翻譯為“興趣點”。在地理信息系統(tǒng)中,一個POI可以是一棟房子、一個商鋪、一個郵筒、一個公交站等。通過本文給大家介紹Android 百度地圖POI搜索功能實例代碼,需要的朋友參考下
    2016-02-02
  • Android網(wǎng)絡監(jiān)聽和網(wǎng)絡判斷示例介紹

    Android網(wǎng)絡監(jiān)聽和網(wǎng)絡判斷示例介紹

    大家好,本篇文章主要講的是Android網(wǎng)絡監(jiān)聽和網(wǎng)絡判斷示例介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Android開發(fā)新手必須知道的10大嚴重錯誤

    Android開發(fā)新手必須知道的10大嚴重錯誤

    這篇文章主要介紹了Android開發(fā)新手必須知道的10大嚴重錯誤,總結(jié)分析了Android開發(fā)中幫助文件、開發(fā)工具、社區(qū)等的重要性以及重要的開發(fā)原則,需要的朋友可以參考下
    2016-01-01
  • Android實現(xiàn)微信右側(cè)頂部下拉對話框

    Android實現(xiàn)微信右側(cè)頂部下拉對話框

    這篇文章主要為大家詳細介紹了Android實現(xiàn)微信右側(cè)頂部下拉對話框,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Android中的Bitmap緩存池使用詳解

    Android中的Bitmap緩存池使用詳解

    這篇文章主要介紹了Android中的Bitmap緩存池使用詳解,本文主要目的是講解如何使用緩存來提高UI的載入輸入和滑動的流暢性,需要的朋友可以參考下
    2015-01-01
  • Android使用LinearLayout設(shè)置邊框

    Android使用LinearLayout設(shè)置邊框

    這篇文章主要介紹了Android如何使用LinearLayout設(shè)置邊框,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Android 中ScrollView與ListView沖突問題的解決辦法

    Android 中ScrollView與ListView沖突問題的解決辦法

    這篇文章主要介紹了Android 中ScrollView與ListView沖突問題的解決辦法的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握解決問題的辦法,需要的朋友可以參考下
    2017-10-10
  • 完全解析Android多線程中線程池ThreadPool的原理和使用

    完全解析Android多線程中線程池ThreadPool的原理和使用

    本篇文章給大家通過原理和實例詳細講述了Android多線程中線程池ThreadPool的原理和使用,對此有興趣的朋友可以跟著參考學習下。
    2018-04-04
  • android開發(fā)教程之文本框加滾動條scrollview

    android開發(fā)教程之文本框加滾動條scrollview

    EditText與TextView加上滾動條其實很簡單,只需要在文本輸入框或者文本顯示框上面加上滾動條控件即可
    2014-02-02

最新評論