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

Android使用Canvas繪制圓形進度條效果

 更新時間:2016年10月13日 15:50:39   作者:低調(diào)小一  
這篇文章主要為大家詳細介紹了Android使用Canvas繪制圓形進度條效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

Android自定義控件經(jīng)常會用到Canvas繪制2D圖形,在優(yōu)化自己自定義控件技能之前,必須熟練掌握Canvas繪圖機制。本文從以下三個方面對Canvas繪圖機制進行講解:

畫布Canvas
畫筆Paint
示例圓形進度條

畫布Canvas

首先,來看一下Android官網(wǎng)對Canvas類的定義:

The Canvas class holds the “draw” calls。To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls(writing into the bitmap), a drawing primitive(eg, Rect, Path, text, Bitmap), and a paint(to describe the colors and styles for the drawing).

簡單來說,Android進行2D繪圖必須要有Canvas類的支持,它位于“android.graphics.Canvas”包下。我們可以把Canvas理解成系統(tǒng)分配給我們的一塊用于繪圖的內(nèi)存(ps:真正的內(nèi)存是其包含的Bitmap)。

Canvas提供了兩個構(gòu)造函數(shù):

Canvas() : 創(chuàng)建一個空的Canvas對象。
Canvas(Bitmap bitmap) : 創(chuàng)建一個以bitmap位圖為背景的Canvas。
通常,我們會采用第二種包含Bitmap參數(shù)的構(gòu)造函數(shù)方式或者直接使用onDraw方法中系統(tǒng)提供的Canvas。

既然Canvas主要用于繪圖,那么它提供了很多相應(yīng)的draw方法,方便我們在Canvas對象上繪圖,介紹幾個常用的draw方法:

void drawRect(RectF rect, Paint paint) : 繪制區(qū)域,參數(shù)為RectF的區(qū)域。
void drawOval(RectF oval, Paint paint) : 繪制矩形的內(nèi)切橢圓。
void drawCircle(float cx, float cy, float radius, Paint paint) : 繪制圓形。cx和cy是圓心坐標,radius是半徑長度。
void drawArc(RectF oval, float startAngle, float sweepAngle. boolean useCenter, Paint paint) : 繪制圓弧形,也是以矩形的內(nèi)切橢圓為標準。其中,startAngle為起始角度,sweepAngle為弧度大小,useCenter為true,則是繪制一個扇行,為false,則只是一段圓弧。(ps:startAngle為0時,是圓形鐘表3點鐘方向)。
void drawPath(Path path, Paint paint) : 根據(jù)給定的path,繪制連線。
void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) : 貼圖,參數(shù)bitmap是要進行繪制的bitmap對象,參數(shù)src是指bitmap的源區(qū)域(一般為null),dst是bitmap的目標區(qū)域,paint是畫筆,可為null。
void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) : 根據(jù)給定的起點和結(jié)束點之間繪制連線。
void drawPoint(float x, float y, Paint paint) : 根據(jù)給定的坐標,繪制點。
void drawText(String text, float x, float y, Paint paint) : 根據(jù)給定的坐標,繪制文字。其中,x是文本起始的x軸坐標,y是文本縱向結(jié)束的y軸坐標。

畫筆Paint

從上面列舉的幾個Canvas.drawXXX()方法可以看到,其中都有一個類型為Paint的參數(shù),可以把它理解成為”畫筆”,通過這個畫筆,在Canvas這張畫布上作畫。它位于“android.graphics.Paint”包下,主要用于設(shè)置繪圖風格,包括畫筆顏色。

Paint中提供了大量設(shè)置繪畫風格的方法,這里僅列出一些常用的功能:

setARGB(int a, int r, int g, int b) : 設(shè)置ARGB顏色。
setColor(int color) : 設(shè)置顏色。
setAlpha(int a) : 設(shè)置透明度。
setAntiAlias(boolean aa) : 設(shè)置是否抗鋸齒。
setShader(Shader shader) : 設(shè)置Paint的填充效果。
setStrokeWidth(float width) : 設(shè)置Paint的筆觸寬度。
setStyle(Paint.Style style) : 設(shè)置Paint的填充風格。
setTextSize(float textSize) : 設(shè)置繪制文本時的文字大小。

自定義圓形進度條

這里以一個自定義的圓形進度條為例,我們首先看一下效果圖:

通過效果圖,我們首先抽象出自定義屬性,如下:

圓環(huán)內(nèi)部填充色。
圓環(huán)進度條的背景色。
圓環(huán)進度條的顏色。
圓環(huán)半徑。
圓環(huán)進度條的寬度。
進度條起始的角度。
中間文字的顏色。
中間文字的大小。
中間文字是否需要顯示的標志位。

在Android中,可以在項目的res/values/目錄下,建立一個resources源文件,通過declare-styleable來聲明一個特定的屬性集合。

示例屬性集合如下所示(res/values/attrs_round_progress_bar.xml):

<resources>
  <declare-styleable name="RoundProgressBar">
    <attr name="startAngle" format="integer"></attr>
    <attr name="radius" format="dimension"></attr>
    <attr name="ringWidth" format="dimension"></attr>
    <attr name="centerColor" format="color"></attr>
    <attr name="ringColor" format="color"></attr>
    <attr name="progressColor" format="color"></attr>
    <attr name="textSize" format="dimension"></attr>
    <attr name="textColor" format="color"></attr>
    <attr name="isTextDisplay" format="boolean"></attr>
  </declare-styleable>
</resources>

自定義的屬性可以在自定義View的構(gòu)造函數(shù)中,通過TypedArray數(shù)組獲取,我們來自定義一個圓形的View來實現(xiàn)上圖的效果(RoundProgressBar.java):

package love.com.progressbar.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import love.com.progressbar.R;


public class RoundProgressBar extends View {
  private static final int START_ANGLE = -90;
  private static final String CENTER_COLOR = "#eeff06";
  private static final String RING_COLOR = "#FF7281E1";
  private static final String PROGRESS_COLOR = "#FFDA0F0F";
  private static final String TEXT_COLOR = "#FF000000";
  private static final int TEXT_SIZE = 30;
  private static final int CIRCLE_RADIUS = 20;
  private static final int RING_WIDTH = 5;

  /**
   * 圓弧的起始角度,參考canvas.drawArc方法
   */
  private int startAngle;

  /**
   * 圓形內(nèi)半徑
   */
  private int radius;

  /**
   * 進度條的寬度
   */
  private int ringWidth;

  /**
   * 默認進度
   */
  private int mProgress = 0;

  /**
   * 圓形內(nèi)部填充色
   */
  private int centerColor;

  /**
   * 進度條背景色
   */
  private int ringColor;

  /**
   * 進度條的顏色
   */
  private int progressColor;

  /**
   * 文字大小
   */
  private int textSize;

  /**
   * 文字顏色
   */
  private int textColor;

  /**
   * 文字是否需要顯示
   */
  private boolean isTextDisplay;

  private String textContent;

  private Paint mPaint;

  public RoundProgressBar(Context context) {
    this(context, null);
  }

  public RoundProgressBar(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    // 獲取自定義屬性
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);
    for (int i = 0; i < a.length(); i ++) {
      int attr = a.getIndex(i);
      switch (attr) {
        case R.styleable.RoundProgressBar_startAngle:
          startAngle = a.getInteger(attr, START_ANGLE);
          break;
        case R.styleable.RoundProgressBar_centerColor:
          centerColor = a.getColor(attr, Color.parseColor(CENTER_COLOR));
          break;
        case R.styleable.RoundProgressBar_progressColor:
          progressColor = a.getColor(attr, Color.parseColor(PROGRESS_COLOR));
          break;
        case R.styleable.RoundProgressBar_ringColor:
          ringColor = a.getColor(attr, Color.parseColor(RING_COLOR));
          break;
        case R.styleable.RoundProgressBar_textColor:
          textColor = a.getColor(attr, Color.parseColor(TEXT_COLOR));
          break;
        case R.styleable.RoundProgressBar_textSize:
          textSize = (int) a.getDimension(attr, TypedValue.applyDimension(
              TypedValue.COMPLEX_UNIT_SP, TEXT_SIZE,
              getResources().getDisplayMetrics()));
          break;
        case R.styleable.RoundProgressBar_isTextDisplay:
          isTextDisplay = a.getBoolean(attr, true);
          break;
        case R.styleable.RoundProgressBar_radius:
          radius = (int) a.getDimension(attr, TypedValue.applyDimension(
              TypedValue.COMPLEX_UNIT_DIP, CIRCLE_RADIUS,
              getResources().getDisplayMetrics()
          ));
          break;
        case R.styleable.RoundProgressBar_ringWidth:
           ringWidth = (int) a.getDimension(attr, TypedValue.applyDimension(
              TypedValue.COMPLEX_UNIT_DIP, RING_WIDTH,
              getResources().getDisplayMetrics()
          ));
          break;
        default:
          break;
      }
    }
    a.recycle();

    // 初始化畫筆設(shè)置
    setPaint();
  }

  private void setPaint() {
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // 獲取圓心坐標
    int cx = getWidth() / 2;
    int cy = cx;

    /**
     * 畫圓心顏色
     */
    if (centerColor != 0) {
      drawCenterCircle(canvas, cx, cy);
    }

    /**
     * 畫外層大圓
     */
    drawOuterCircle(canvas, cx, cy);

    /**
     * 畫進度圓弧
     */
    drawProgress(canvas, cx, cy);

    /**
     * 畫出進度百分比
     */
    drawProgressText(canvas, cx, cy);
  }

  private void drawProgressText(Canvas canvas, int cx, int cy) {
    if (!isTextDisplay) {
      return;
    }
    mPaint.setColor(textColor);
    mPaint.setTextSize(textSize);
    mPaint.setTypeface(Typeface.DEFAULT_BOLD);
    mPaint.setStrokeWidth(0);
    textContent = getProgress() + "%";
    float textWidth = mPaint.measureText(textContent);
    canvas.drawText(textContent, cx - textWidth / 2, cy + textSize / 2, mPaint);
  }

  private void drawProgress(Canvas canvas, int cx, int cy) {
    mPaint.setColor(progressColor);
    mPaint.setStrokeWidth(ringWidth);
    mPaint.setStyle(Paint.Style.STROKE);
    RectF mRectF = new RectF(cx - radius, cy - radius, cx + radius, cy + radius);
    float sweepAngle = (float) (mProgress * 360.0 / 100);
    canvas.drawArc(mRectF, startAngle, sweepAngle, false, mPaint);
  }

  private void drawOuterCircle(Canvas canvas, int cx, int cy) {
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setColor(ringColor);
    mPaint.setStrokeWidth(ringWidth);
    canvas.drawCircle(cx, cy, radius, mPaint);
  }

  private void drawCenterCircle(Canvas canvas, int cx, int cy) {
    mPaint.setColor(centerColor);
    mPaint.setStyle(Paint.Style.FILL);
    canvas.drawCircle(cx, cy, radius, mPaint);
  }


  public synchronized int getProgress() {
    return mProgress;
  }

  public synchronized void setProgress(int progress) {
    if (progress < 0) {
      progress = 0;
    } else if (progress > 100) {
      progress = 100;
    }
    mProgress = progress;
    // 進度改變時,需要通過invalidate方法進行重繪
    postInvalidate();
  }
}

在MainActivity.java的布局文件中,可以這樣調(diào)用圓形進度條:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:round="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <love.com.progressbar.view.RoundProgressBar
    android:id="@+id/id_round_progressbar"
    android:layout_width="400dp"
    android:layout_height="400dp"
    round:radius="100dp"
    round:ringWidth="20dp"
    round:startAngle="-90"
    round:centerColor="#eeff06"
    round:ringColor="#e16556e6"
    round:progressColor="#d20c0c"
    round:textColor="#000000"
    round:textSize="20sp"
    round:isTextDisplay="true"/>
</RelativeLayout>

其中,xmlns:round=”http://schemas.android.com/apk/res-auto是Android Studio中增加的導(dǎo)入自定義View屬性的命名空間寫法。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android序列化XML數(shù)據(jù)

    Android序列化XML數(shù)據(jù)

    有時候一些項目中需要傳遞一些XML格式的數(shù)據(jù),如何把一個對象序列化為XML格式,本文就講講Android序列化XML數(shù)據(jù)的方法
    2013-11-11
  • android判斷相機圖片朝向的簡單方法

    android判斷相機圖片朝向的簡單方法

    下面小編就為大家?guī)硪黄猘ndroid判斷相機圖片朝向的簡單方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • android?ViewPager實現(xiàn)一個無限輪播圖

    android?ViewPager實現(xiàn)一個無限輪播圖

    大家好,本篇文章主要講的是android?ViewPager實現(xiàn)一個無限輪播圖,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • Kotlin 協(xié)程與掛起函數(shù)及suspend關(guān)鍵字深入理解

    Kotlin 協(xié)程與掛起函數(shù)及suspend關(guān)鍵字深入理解

    這篇文章主要為大家介紹了Kotlin 協(xié)程與掛起函數(shù)及suspend關(guān)鍵字深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Android仿知乎日報開屏頁效果

    Android仿知乎日報開屏頁效果

    這篇文章主要為大家詳細介紹了Android仿知乎日報開屏頁效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Android設(shè)置圖片圓角的方法

    Android設(shè)置圖片圓角的方法

    這篇文章主要為大家詳細介紹了Android設(shè)置圖片圓角的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Android啟動畫面的實現(xiàn)方法

    Android啟動畫面的實現(xiàn)方法

    這篇文章主要介紹了Android啟動畫面的實現(xiàn)方法,分析了布局文件及加載啟動文件的實現(xiàn)方法,非常具有實用價值,需要的朋友可以參考下
    2015-01-01
  • Android實現(xiàn)拍照截圖功能

    Android實現(xiàn)拍照截圖功能

    這篇文章主要介紹了Android實現(xiàn)拍照截圖功能,簡單介紹了Android實現(xiàn)拍照截圖功能的步驟,供大家參考,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Android寫一個實時輸入框功能

    Android寫一個實時輸入框功能

    這篇文章主要介紹了Android寫一個實時輸入框功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Android開發(fā)之圓角矩形創(chuàng)建工具RoundRect類定義與用法分析

    Android開發(fā)之圓角矩形創(chuàng)建工具RoundRect類定義與用法分析

    這篇文章主要介紹了Android開發(fā)之圓角矩形創(chuàng)建工具RoundRect類定義與用法,結(jié)合完整實例形式分析了Android圓角矩形工具類的定義與簡單使用技巧,需要的朋友可以參考下
    2018-01-01

最新評論