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

Android開發(fā)自定義控件之折線圖實(shí)現(xiàn)方法詳解

 更新時(shí)間:2020年05月21日 11:36:07   作者:LIFE_R  
這篇文章主要介紹了Android開發(fā)自定義控件之折線圖實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Android自定義控件中折線圖原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了Android開發(fā)自定義控件之折線圖實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:

前言

折線圖是Android開發(fā)中經(jīng)常會(huì)碰到的效果,但由于涉及自定義View的知識(shí),對(duì)許多剛?cè)腴T的小白來說會(huì)覺得很高深。其實(shí)不然,接下來我就以盡量通俗的語言來說明下圖折線圖效果的實(shí)現(xiàn)過程。

效果圖

實(shí)現(xiàn)過程

首先,選擇自定義控件的方式。

自定義控件的實(shí)現(xiàn)有四種方式:

1.繼承View,重寫onDraw、onMeasure等方法。
2.繼承已有的View(比如TextView)。
3.繼承ViewGroup實(shí)現(xiàn)自定義布局。
4.繼承已有的ViewGroup(比如LinearLayout)。

由于我們不需要多個(gè)控件進(jìn)行組合,也不需要在原有控件基礎(chǔ)上改造,故我們采用第1種方式即繼承View來實(shí)現(xiàn)。代碼如下,新建一個(gè)ChartView類繼承自View,并實(shí)現(xiàn)他的幾個(gè)構(gòu)造方法,并重寫onDraw和onMeasure方法,因?yàn)槲覀円趏nDraw方法里面進(jìn)行繪制工作,并且我希望這個(gè)控件的長(zhǎng)寬是相等的,所以在onMeasure方法設(shè)置寬高相等。設(shè)置長(zhǎng)寬相等的方式很簡(jiǎn)單,我們不需要自己去測(cè)量實(shí)現(xiàn),只需要調(diào)用父類的onMeasure方法,傳參數(shù)(寬高值)時(shí)將都傳入寬度(或者高度)即可。

public class ChartView extends View {

  public ChartView(Context context) {
    super(context);
  }

  public ChartView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
  }

  public ChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
  }

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

其次,繪制簡(jiǎn)單圖形并顯示出來。

在進(jìn)行繪制之前,我們要進(jìn)行若干初始化工作,其中就包括畫筆的初始化。然后就可以進(jìn)行繪制了,我們先繪制一個(gè)簡(jiǎn)單的圓圈,然后將控件放到布局文件中,運(yùn)行看看效果。

ChartView代碼

public class ChartView extends View {

  // 畫筆
  private Paint paint;

  /**
  * 構(gòu)造函數(shù)
  */
  public ChartView(Context context) {
    super(context);
    initWork();
  }

  /**
  * 構(gòu)造函數(shù)
  */
  public ChartView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    initWork();
  }

  /**
  * 構(gòu)造函數(shù)
  */
  public ChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initWork();
  }

  /**
  * 初始化工作
  */
  private void initWork() {
    initPaint();
  }

  /**
  * 畫筆設(shè)置
  */
  private void initPaint() {
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    // 畫筆樣式為填充
    paint.setStyle(Paint.Style.FILL);
    // 顏色設(shè)為紅色
    paint.setColor(Color.RED);
    // 寬度為3像素
    paint.setStrokeWidth(3);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 畫圓
    canvas.drawCircle(300,300,100,paint);
  }
}

activity_main.xml

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

  <com.toprs.linechart.ChartView
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</android.support.constraint.ConstraintLayout>

效果:

然后,繪制圖表。

到目前為止,已經(jīng)實(shí)現(xiàn)了最簡(jiǎn)單的一個(gè)自定義控件,雖然它什么功能都沒有,只是簡(jiǎn)單顯示一個(gè)紅色圓圈,但本質(zhì)都是一樣的。接下來就開始圖表的繪制。

1.初始化一些需要使用的值。

  // 刻度之間的距離
  private int degreeSpace;

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 控件上下左右邊界四至及控件的寬度(同時(shí)也是高度!)
    int left = getLeft();
    int right = getRight();
    int top = getTop();
    int bottom = getBottom();
    int w = getWidth();

    // 圖表距離控件邊緣的距離
    int graphPadding = w / 10;
    // 圖表上下左右四至
    int graphLeft = left + graphPadding;
    int graphBottom = bottom - graphPadding;
    int graphRight = right - graphPadding;
    int graphTop = top + graphPadding;
    // 圖表寬度(也等同高度奧~)
    int graphW = graphRight - graphLeft;
    // 刻度之間的距離
    degreeSpace = graphW / 8;
  }

2.灰色背景

  // 背景
  canvas.drawColor(Color.LTGRAY);

3.坐標(biāo)系

  // 畫筆設(shè)置樣式為STROKE樣式,即只劃線不填充
  paint.setStyle(Paint.Style.STROKE);

  // 坐標(biāo)系繪制
  Path pivotPath = new Path();
  //Y軸
  pivotPath.moveTo(graphLeft, graphBottom);
  pivotPath.lineTo(graphLeft, graphTop);
  //Y軸箭頭
  pivotPath.lineTo(graphLeft - 12, graphTop + 20);
  pivotPath.moveTo(graphLeft, graphTop);
  pivotPath.lineTo(graphLeft + 12, graphTop + 20);
  //X軸
  pivotPath.moveTo(graphLeft, graphBottom);
  pivotPath.lineTo(graphRight, graphBottom);
  //X軸箭頭
  pivotPath.lineTo(graphRight - 20, graphBottom + 12);
  pivotPath.moveTo(graphRight, graphBottom);
  pivotPath.lineTo(graphRight - 20, graphBottom - 12);
  canvas.drawPath(pivotPath, paint);

4.刻度虛線及數(shù)字

  // Y軸刻度虛線
  for (int i = 1; i < 8; i++) {
    Path yKeduPath = new Path();
    // 線
    paint.setColor(Color.WHITE);
    paint.setStrokeWidth(1);
    paint.setStyle(Paint.Style.STROKE);
    paint.setPathEffect(new DashPathEffect(new float[]{5,5},0));
    yKeduPath.moveTo(graphLeft, graphBottom - i * degreeSpace);
    yKeduPath.lineTo(graphRight, graphBottom - i * degreeSpace);
    canvas.drawPath(yKeduPath, paint);
    // 數(shù)字
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.FILL);
    paint.setTextSize(25);
    paint.setPathEffect(null);
    canvas.drawText(i + "", graphPadding / 2, graphBottom - i * degreeSpace, paint);
  }
  // X軸刻度虛線
  for (int i = 1; i < 8; i++) {
    Path xKeduPath = new Path();
    // 線
    paint.setColor(Color.WHITE);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(1);
    paint.setPathEffect(new DashPathEffect(new float[]{5,5},0));
    xKeduPath.moveTo(graphLeft + i * degreeSpace, graphBottom);
    xKeduPath.lineTo(graphLeft + i * degreeSpace, graphTop);
    canvas.drawPath(xKeduPath, paint);
    // 數(shù)字
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.FILL);
    paint.setTextSize(25);
    paint.setPathEffect(null);
    canvas.drawText(i + "", graphLeft + i * degreeSpace, graphBottom + graphPadding / 2, paint);
  }

5.折線

在繪制折線之前,我們先要初始化幾個(gè)參數(shù)。

  // 模擬數(shù)據(jù)
  private float[] data = {3.2f, 4.3f, 2.5f, 3.2f, 3.8f, 7.1f, 1.3f, 5.6f};
  // 當(dāng)前顯示的數(shù)據(jù)數(shù)量
  private int showNum=1;

  // 折線
  Path linePath = new Path();
  for (int i = 0; i < showNum; i++) {
    int toPointX = graphLeft + i * degreeSpace;
    int toPointY = graphBottom - ((int) (data[i] * degreeSpace));
    paint.setColor(Color.YELLOW);
    paint.setStyle(Paint.Style.STROKE);
    if (i==0){
      linePath.moveTo(toPointX,toPointY);
    }else {
      linePath.lineTo(toPointX, toPointY);
    }
    // 節(jié)點(diǎn)圓圈
    canvas.drawCircle(toPointX, toPointY,10,paint);
    paint.setColor(Color.WHITE);
    paint.setStyle(Paint.Style.FILL);
    canvas.drawCircle(toPointX,toPointY,7,paint);
  }
  paint.setColor(Color.YELLOW);
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(3);
  canvas.drawPath(linePath, paint);

6.讓圖表動(dòng)起來

為了實(shí)現(xiàn)數(shù)據(jù)依次顯現(xiàn)的動(dòng)畫,我們開啟一個(gè)線程是當(dāng)前顯示的數(shù)據(jù)數(shù)量即showNum變量不斷加一,并間隔時(shí)間0.5秒。然后postInvalidate()重繪即可。

  private void initWork() {
    initPaint(); 
    // 開啟線程,沒隔0.5秒showNum加一
    new Thread(new Runnable() {
      @Override
      public void run() {
        while (true){
          if (showNum<data.length){
            showNum++;
          }else {
            showNum=1;
          }
          // 重繪
          postInvalidate();
          // 休眠0.5秒
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }).start();
  }

好了,運(yùn)行一下,便會(huì)實(shí)現(xiàn)上面的效果了。如果你覺得效果不夠炫酷或者功能太少,那就自己完善吧~~

結(jié)語

由于自定義控件是Android進(jìn)階路上必然要碰到的知識(shí),所以希望大家重視。其實(shí)自定義控件說難也難說簡(jiǎn)單也簡(jiǎn)單。實(shí)現(xiàn)一些普通的效果還是很方便的,像這次舉的例子,但如果要實(shí)現(xiàn)各種炫酷效果并且要完善各種功能的話,就需要各種知識(shí)的配合了,包括數(shù)學(xué)、物理、繪圖等知識(shí)。所以還是需要平時(shí)不斷積累的,看到別人的控件很棒的時(shí)候自己可以試著去實(shí)現(xiàn)一下,對(duì)自己的知識(shí)庫不斷進(jìn)行補(bǔ)充,自然會(huì)嫻熟的運(yùn)用。本人也是菜鳥一枚,望共勉?。?/p>

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android控件用法總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android視圖View技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android數(shù)據(jù)庫操作技巧總結(jié)》及《Android資源操作技巧匯總

希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。

相關(guān)文章

最新評(píng)論