Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 安卓柱狀圖

安卓柱狀圖

編輯:關於Android編程

今天做項目需要用到簡單的橫向的柱狀圖,上網查了一下,沒找到合適的框架,於是決定自己動手寫一個自定義View,來實現三種柱狀圖。

那麼先看效果圖

\

橫向的柱狀圖,只有柱子的比例和文字。

 

\

縱向的柱狀圖,加上了坐標軸的繪制。

 

 

 

 

 

\

 

 

比例式柱狀圖,只接受長度為2的數組,會自己判斷將長的置於背景。

 

 

 

 

 

 

那麼我們看一下這個自定義View的代碼:

 

package com.example.day09;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;

/**
 * Created by Administrator on 2016/11/3.
 */

public class Histogram extends View {
    private int[] nums;
    private String[] names;
    private int[] colors;
    private Context context;
    private int max = 0;
    private int type;
    private int wheretext;
    private int maxlong;
    private int j;
    private int width;
    private int kong;
    private boolean useAnimation;
    private Histogram v;

    public void setNames(String[] names) {
        this.names = names;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public void setType(int type) {
        this.type = type;
    }

    public void setWheretext(int wheretext) {
        this.wheretext = wheretext;
    }

    public void setMaxlong(int maxlong) {
        this.maxlong = maxlong;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public void setKong(int kong) {
        this.kong = kong;
    }


    public void setUseAnimation(boolean useAnimation) {
        this.useAnimation = useAnimation;
    }


    public Histogram(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        v = this;
    }

    public Histogram(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        v = this;
    }

    public Histogram(Context context) {
        super(context);
        v = this;
        this.context = context;
    }

    /**
     * 初始化柱狀圖的方法
     *
     * @param nums      存放每個元素數量的數組
     * @param names     存放每個元素文字的數組
     * @param colors    存放每個元素使用的顏色的數組
     * @param type      定義柱狀圖的類型 1為橫向,2為縱向,其余為比例
     * @param wheretext 定義柱狀圖文字的位置  (若橫向)1為圖前,2為圖後,其余為無文字;(若縱向)1為圖下,其余無文字
     * @param maxlong   柱狀圖的最大長度(px)
     * @param max       最大長度對應的數值
     * @param width     每條柱子的寬度
     * @param kong      柱子之間的空隙寬度
     */
    public void SetHistogram(int[] nums, String[] names, int[] colors, int type, int wheretext, int maxlong, int max, int width, int kong, boolean useAnimation) {
        this.colors = colors;
        this.names = names;
        this.nums = nums;
        this.type = type;
        this.wheretext = wheretext;
        this.maxlong = maxlong;
        this.max = max;
        j = maxlong / max;
        this.width = width;
        this.kong = kong;
        this.useAnimation = useAnimation;
    }

    public void SetHistogram(int[] nums, int[] colors, int type) {
        SetHistogram(nums, null, colors, type, 0, 800, 100, 50, 0, false);
    }

    public void SetHistogram(int[] nums, int[] colors) {
        SetHistogram(nums, colors, 1);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        switch (type) {
            case 1:
                DrawHeng(canvas, p);
                break;
            case 2:
                DrawShu(canvas, p);
                break;
            default:
                DrawBiLi(canvas, p);
                break;
        }

    }

    /**
     * 畫橫向比例柱狀圖
     *
     * @param canvas
     * @param p
     */
    private void DrawBiLi(Canvas canvas, Paint p) {
        int i, j;
        if (nums[0] > nums[1]) {
            i = 0;
            j = 1;
        } else {
            i = 1;
            j = 0;
        }
        int[] numss = new int[]{nums[i], nums[j]};
        int[] colorss = new int[]{colors[i], colors[j]};
        String[] namess = new String[]{names[i], names[j]};
        float bili = (0.0F + numss[0]) / (0.0F + numss[1]);
        switch (wheretext) {
            case 1:
                p.setColor(colorss[0]);
                canvas.drawRect(0, 0, maxlong, width, p);
                p.setColor(colorss[1]);
                canvas.drawRect(0, 0, maxlong / bili, width, p);
                //寫字
                p.setColor(Color.WHITE);
                p.setTextSize(width - 10);
                p.setTextAlign(Paint.Align.LEFT);
                canvas.drawText(namess[0], 10, width, p);
                canvas.drawText(namess[1], maxlong / bili + 10, width, p);
                if (useAnimation) {
                    setAnimationHeng();
                }
                break;
            default:
                p.setColor(colorss[0]);
                canvas.drawRect(0, 0, maxlong, width, p);
                p.setColor(colorss[1]);
                canvas.drawRect(0, 0, maxlong / bili, width, p);
                if (useAnimation) {
                    setAnimationHeng();
                }
                break;
        }

    }

    /**
     * 畫縱向柱狀圖
     *
     * @param canvas
     * @param p
     */
    private void DrawShu(Canvas canvas, Paint p) {
        switch (wheretext) {
            case 1:
                //畫坐標軸
                p.setStrokeWidth(5);
                p.setColor(Color.BLACK);
                canvas.drawLine(30, maxlong, nums.length * (width + kong) + 150, maxlong, p);
                canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong - 30, p);
                canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong + 30, p);
                canvas.drawLine(30, maxlong, 30, 0, p);
                canvas.drawLine(30, 0, 0, 30, p);
                canvas.drawLine(30, 0, 60, 30, p);
                //畫柱子
                for (int i = 0; i < nums.length; i++) {
                    p.setColor(colors[i]);
                    canvas.drawRect(60 + kong + (i * (kong + width)), maxlong - (j * nums[i]), 60 + kong + (i * (kong + width)) + width, maxlong, p);
                    p.setColor(Color.BLACK);
                    p.setTextSize(width - 10);
                    p.setTextAlign(Paint.Align.LEFT);
                    canvas.drawText(names[i], 60 + ((width + kong) * i) + width / 4, maxlong + width, p);
                }
                if (useAnimation) {
                    setAnimationShu();
                }
                break;

            default:
                //畫坐標軸
                p.setStrokeWidth(5);
                p.setColor(Color.BLACK);
                canvas.drawLine(30, maxlong, nums.length * (width + kong) + 150, maxlong, p);
                canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong - 30, p);
                canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong + 30, p);
                canvas.drawLine(30, maxlong, 30, 0, p);
                canvas.drawLine(30, 0, 0, 30, p);
                canvas.drawLine(30, 0, 60, 30, p);
                //畫柱子
                for (int i = 0; i < nums.length; i++) {
                    p.setColor(colors[i]);
                    canvas.drawRect(60 + kong + (i * (kong + width)), maxlong - (j * nums[i]), 60 + kong + (i * (kong + width)) + width, maxlong, p);
                }
                if (useAnimation) {
                    setAnimationShu();
                }
                break;
        }

    }

    /**
     * 畫橫向柱狀圖
     *
     * @param canvas
     * @param p
     */
    private void DrawHeng(Canvas canvas, Paint p) {
        switch (wheretext) {
            case 1:
                for (int i = 0; i < nums.length; i++) {
                    p.setColor(Color.BLACK);
                    p.setTextSize(width - 10);
                    p.setTextAlign(Paint.Align.RIGHT);
                    canvas.drawText(names[i], 80, width + width * i, p);
                    p.setColor(colors[i]);
                    canvas.drawRect(100, i * width + kong, 100 + nums[i] * j, width + i * width, p);
                    if (useAnimation) {
                        setAnimationHeng();
                    }
                }
                break;
            case 2:
                for (int i = 0; i < nums.length; i++) {

                    p.setColor(colors[i]);
                    canvas.drawRect(0, i * width + kong, nums[i] * j, width + i * width, p);
                    p.setColor(Color.BLACK);
                    p.setTextSize(width - 10);
                    p.setTextAlign(Paint.Align.LEFT);
                    canvas.drawText(names[i], nums[i] * j + 20, width + width * i, p);
                    if (useAnimation) {
                        setAnimationHeng();
                    }
                }
                break;
            default:
                for (int i = 0; i < nums.length; i++) {

                    p.setColor(colors[i]);
                    canvas.drawRect(0, i * width + kong, nums[i] * j, width + i * width, p);
                    if (useAnimation) {
                        setAnimationHeng();
                    }
                }
                break;
        }

    }

    /**
     * 設置動畫(橫向)
     */
    private void setAnimationHeng() {
        ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 1.0f, 1.0f
                , Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        scaleAnimation.setDuration(1000);
        this.setAnimation(scaleAnimation);
        scaleAnimation.startNow();
    }

    /**
     * 設置動畫(橫向)
     */
    private void setAnimationShu() {
        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f
                , Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        scaleAnimation.setDuration(1000);
        this.setAnimation(scaleAnimation);
        scaleAnimation.startNow();
    }
}

其中,設置所有參數的方法為

 

 

 /**
     * 初始化柱狀圖的方法
     *
     * @param nums      存放每個元素數量的數組
     * @param names     存放每個元素文字的數組
     * @param colors    存放每個元素使用的顏色的數組
     * @param type      定義柱狀圖的類型 1為橫向,2為縱向,其余為比例
     * @param wheretext 定義柱狀圖文字的位置  (若橫向)1為圖前,2為圖後,其余為無文字;(若縱向)1為圖下,其余無文字
     * @param maxlong   柱狀圖的最大長度(px)
     * @param max       最大長度對應的數值
     * @param width     每條柱子的寬度
     * @param kong      柱子之間的空隙寬度
     */
    public void SetHistogram(int[] nums, String[] names, int[] colors, int type, int wheretext, int maxlong, int max, int width, int kong, boolean useAnimation) {
        this.colors = colors;
        this.names = names;
        this.nums = nums;
        this.type = type;
        this.wheretext = wheretext;
        this.maxlong = maxlong;
        this.max = max;
        j = maxlong / max;
        this.width = width;
        this.kong = kong;
        this.useAnimation = useAnimation;
    }
後面的代碼都是根據這個方法傳進來的參數做出相應的繪制,當然,大多數有用的屬性也單獨提供了Set方法;

 

 

 

 

 

 

接下來我們簡單的試驗一下一個縱向的柱狀圖,代碼如下:

MainActivity:

 

package com.example.day09;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;

public class MainActivity extends Activity {
	Histogram histogram;
			int[] nums;
	int[] colors;
	String[] names;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		histogram= (Histogram) findViewById(R.id.imageId);
		nums=new int[]{55,24,64,35,100};
		colors=new int[]{Color.BLUE,Color.YELLOW,0Xffabcdef,Color.GREEN,Color.RED};
		names=new String[]{"A","B","C","D","E"};
		histogram.SetHistogram(nums,names,colors,2,1,1000,100,80,10,false);
		ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 1.0f, 1.0f
				, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
		scaleAnimation.setDuration(1000);
		histogram.setAnimation(scaleAnimation);
		scaleAnimation.startNow();
		scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {

			}

			@Override
			public void onAnimationEnd(Animation animation) {
				histogram.setVisibility(View.VISIBLE);
			}

			@Override
			public void onAnimationRepeat(Animation animation) {

			}
		});
	}

	
	
	

}

布局文件:

 

 



    


這樣就做出了一個簡單的柱狀圖了,截圖效果:

 

\

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved