Android自訂View------柱狀統計圖,androidview------

來源:互聯網
上載者:User

Android自訂View------柱狀統計圖,androidview------

關於自訂View,相信多數開發人員都已經非常熟悉了,網路上的例子也非常多,各種炫酷吊炸天的自訂View也層出不窮。本文只是一個初級學習教程,對於初學者有參考價值。

下面正式進入主題。

本文採用自訂View的方式實現柱狀統計圖BarGraphView,實現了柱狀統計圖的準系統,因為本身是為了學習自訂View,因此擴充性比較差,只能作為自訂View的參考。

上:



View顯示到螢幕上主要經過這三個過程

(1)Measure(測量)

首先View需要測量自身的大小,包括長和寬。 當View類的成員函數measure決定要重新測量當前View的寬度和高度之後,會去調用另外一個成員函數onMeasure來真正執行測量寬度和高度的操作。因此,自訂View大多都需要覆寫onMeasure方法來測量View的大小。onMeasure方法如下:

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

其中widthMeasureSpec和heightMeasureSpec兩個參數為父視圖的建議大小。 參數measureSpec的值其實是由兩部分內容來組成的,最高2位表示一個測量模式,而低30位表示一個寬度值或者高度值,測量模式有三種,分別是MeasureSpec.EXACTLY、MeasureSpec.UNSPECIFIED和MeasureSpec.AT_MOST,這裡就不講三種模式的區別了。在BarGraphView中將會參考這個兩個數值來確定BarGraphView的大小。

(2)Layout(布局)

這個過程只在View容器(ViewGroup及其子類)有用,因為非容器類View在螢幕中的位置操作由父控制項來決定,所以不需要覆寫onLayout()方法。

(3)Draw(繪製)

最後繪製View的過程,在這個過程裡主要通過Paint對象在Canvas上面繪製相應映像,最終把View展現在螢幕上。 對於自訂View來說,通常需要覆寫onDraw()方法繪製View。

    @Override    public void onDraw(Canvas canvas) {    }
該方法提供了一塊畫布,我們只需要建立一個畫筆在畫布上繪圖案即可。


好了,瞭解了上述過程,接下來我們開始實現BarGraphView。

BarGraphView主要代碼集中在Draw的過程,通過onDraw方法把統計圖繪製到螢幕上來。

經過分析,把柱狀圖分為以下幾部分

1.橫/垂直軸

2.橫/垂直軸刻度標記

3.橫/垂直軸刻度值

4.橫/垂直軸箭頭

5.標題

6.柱狀圖

針對不同部分利用drawLine()(畫直線)、drawText()(畫文字)、drawPath()(畫多邊形)以及drawRect()(畫矩形)的方法分別繪製相應圖案。

以下是BarGraphView類代碼,可以直接看注釋。

package com.eleven.demo.widget;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.view.View;import com.eleven.demo.R;/** * Created by Eleven on 2015/5/3. */public class BarGraphView extends View {    private final String TAG = BarGraphView.class.getName();    //畫筆    private Paint mPaint;    //標題    private String title;    //標題顏色    private int titleColor;    //標題大小    private float titleSize;    //X座標軸最大值    private float maxAxisValueX = 900;    //X座標軸刻度標記數量    private int axisDivideSizeX = 9;    //Y座標軸最大值    private float maxAxisValueY = 700;    //Y座標軸刻度標記數量    private int axisDivideSizeY = 7;    //視圖寬度    private int width;    //視圖高度    private int height;    //座標原點位置    private final int originX = 100;    private final int originY = 800;    //柱狀圖資料    private int columnInfo[][];    public BarGraphView(Context context, AttributeSet attrs) {        super(context, attrs);        //建立畫筆        mPaint = new Paint();        //擷取配置的屬性值        TypedArray mArray = context.obtainStyledAttributes(attrs, R.styleable.BarGraphView);        title = mArray.getString(R.styleable.BarGraphView_barGraph_title);        titleColor = mArray.getColor(R.styleable.BarGraphView_barGraph_titleColor, Color.BLACK);        titleSize = mArray.getDimension(R.styleable.BarGraphView_barGraph_titleSize, 36);    }    /**     * 設定X軸的最大值及刻度標記數量(包括0座標刻度)     *     * @param maxValue   X軸的最大值     * @param divideSize 刻度標記數量     */    public void setAxisX(float maxValue, int divideSize) {        maxAxisValueX = maxValue;        axisDivideSizeX = divideSize;    }    /**     * 設定Y軸的最大值及刻度標記數量(包括0座標刻度)     *     * @param maxValue   Y軸的最大值     * @param divideSize 刻度標記數量     */    public void setAxisY(float maxValue, int divideSize) {        maxAxisValueY = maxValue;        axisDivideSizeY = divideSize;    }    /**     * 設定柱狀圖資料     *     * @param columnInfo     */    public void setColumnInfo(int[][] columnInfo) {        this.columnInfo = columnInfo;    }    @Override    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        width = MeasureSpec.getSize(widthMeasureSpec) - 200;        height = MeasureSpec.getSize(heightMeasureSpec) - 800;    }    @Override    public void onDraw(Canvas canvas) {        drawAxisX(canvas, mPaint);        drawAxisY(canvas, mPaint);        drawAxisScaleMarkX(canvas, mPaint);        drawAxisScaleMarkY(canvas, mPaint);        drawAxisArrowsX(canvas, mPaint);        drawAxisArrowsY(canvas, mPaint);        drawAxisScaleMarkValueX(canvas, mPaint);        drawAxisScaleMarkValueY(canvas, mPaint);        drawColumn(canvas, mPaint);        drawTitle(canvas, mPaint);    }    /**     * 繪製橫座標軸(X軸)     *     * @param canvas     * @param paint     */    private void drawAxisX(Canvas canvas, Paint paint) {        paint.setColor(Color.BLACK);        //設定畫筆寬度        paint.setStrokeWidth(5);        //設定畫筆消除鋸齒        paint.setAntiAlias(true);        //畫橫軸(X)        canvas.drawLine(originX, originY, originX + width, originY, paint);    }    /**     * 繪製垂直軸(Y軸)     *     * @param canvas     * @param paint     */    private void drawAxisY(Canvas canvas, Paint paint) {        //畫豎軸(Y)        canvas.drawLine(originX, originY, originX, originY - height, paint);//參數說明:起始點左邊x,y,終點座標x,y,畫筆    }    /**     * 繪製橫座標軸刻度標記(X軸)     *     * @param canvas     * @param paint     */    private void drawAxisScaleMarkX(Canvas canvas, Paint paint) {        float cellWidth = width / axisDivideSizeX;        for (int i = 0; i < axisDivideSizeX - 1; i++) {            canvas.drawLine(cellWidth * (i + 1) + originX, originY, cellWidth * (i + 1) + originX, originY - 10, paint);        }    }    /**     * 繪製垂直軸刻度標記(Y軸)     *     * @param canvas     * @param paint     */    private void drawAxisScaleMarkY(Canvas canvas, Paint paint) {        float cellHeight = height / axisDivideSizeY;        for (int i = 0; i < axisDivideSizeY - 1; i++) {            canvas.drawLine(originX, (originY - cellHeight * (i + 1)), originX + 10, (originY - cellHeight * (i + 1)), paint);        }    }    /**     * 繪製橫座標軸刻度值(X軸)     *     * @param canvas     * @param paint     */    private void drawAxisScaleMarkValueX(Canvas canvas, Paint paint) {        //設定畫筆繪製文字的屬性        paint.setColor(Color.GRAY);        paint.setTextSize(28);        paint.setFakeBoldText(true);        float cellWidth = width / axisDivideSizeX;        float cellValue = maxAxisValueX / axisDivideSizeX;        for (int i = 1; i < axisDivideSizeX; i++) {            canvas.drawText(String.valueOf(cellValue * i), cellWidth * i + originX - 35, originY + 30, paint);        }    }    /**     * 繪製垂直軸刻度值(Y軸)     *     * @param canvas     * @param paint     */    private void drawAxisScaleMarkValueY(Canvas canvas, Paint paint) {        float cellHeight = height / axisDivideSizeY;        float cellValue = maxAxisValueY / axisDivideSizeY;        for (int i = 1; i < axisDivideSizeY; i++) {            canvas.drawText(String.valueOf(cellValue * i), originX - 80, originY - cellHeight * i + 10, paint);        }    }    /**     * 繪製橫座標軸箭頭(X軸)     *     * @param canvas     * @param paint     */    private void drawAxisArrowsX(Canvas canvas, Paint paint) {        //畫三角形(X軸箭頭)        Path mPathX = new Path();        mPathX.moveTo(originX + width + 30, originY);//起始點        mPathX.lineTo(originX + width, originY - 10);//下一點        mPathX.lineTo(originX + width, originY + 10);//下一點        mPathX.close();        canvas.drawPath(mPathX, paint);    }    /**     * 繪製垂直軸箭頭(Y軸)     *     * @param canvas     * @param paint     */    private void drawAxisArrowsY(Canvas canvas, Paint paint) {        //畫三角形(Y軸箭頭)        Path mPathX = new Path();        mPathX.moveTo(originX, originY - height - 30);//起始點        mPathX.lineTo(originX - 10, originY - height);//下一點        mPathX.lineTo(originX + 10, originY - height);//下一點        mPathX.close();        canvas.drawPath(mPathX, paint);    }    /**     * 繪製柱狀圖     *     * @param canvas     * @param paint     */    private void drawColumn(Canvas canvas, Paint paint) {        if(columnInfo == null)            return;        float cellWidth = width / axisDivideSizeX;        for (int i = 0; i < columnInfo.length; i++) {            paint.setColor(columnInfo[i][1]);            float leftTopY = originY - height * columnInfo[i][0] / maxAxisValueY;            canvas.drawRect(originX + cellWidth * (i + 1), leftTopY, originX + cellWidth * (i + 2), originY, mPaint);//左上方x,y右下角x,y,畫筆        }    }    /**     * 繪製標題     *     * @param canvas     * @param paint     */    private void drawTitle(Canvas canvas, Paint paint) {        //畫標題        if (title != null) {            //設定畫筆繪製文字的屬性            mPaint.setColor(titleColor);            mPaint.setTextSize(titleSize);            mPaint.setFakeBoldText(true);            canvas.drawText(title, 300, originY + 150, paint);        }    }}



MainActivity的布局檔案:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:eleven="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <com.eleven.demo.widget.BarGraphView        android:id="@+id/custom_view"        android:layout_width="600dp"        android:layout_height="wrap_content"        eleven:barGraph_title="自訂柱狀圖"        eleven:barGraph_titleSize="24sp"        eleven:barGraph_titleColor="@android:color/black"/></RelativeLayout>

MainActivity中使用

public class MainActivity extends ActionBarActivity {    private BarGraphView mBarGraphView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView(){        mBarGraphView = (BarGraphView)findViewById(R.id.custom_view);        mBarGraphView.setAxisX(900, 9);        mBarGraphView.setAxisY(700,7);        int columnInfo[][] = new int[][]{{600, Color.BLUE},{500, Color.GREEN},{400, Color.RED},{300, Color.BLUE},                {500, Color.YELLOW},{300, Color.LTGRAY},{200, Color.BLUE}};        mBarGraphView.setColumnInfo(columnInfo);    }


該自訂View的實現中使用了自訂屬性的方式定義了三個屬性值,關於attrs.xml檔案的使用方式參考 http://blog.csdn.net/jiangwei0910410003/article/details/17006087


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.