Android 如何 画 柱状图 -------自定义View



实现了 柱状图 根据 SeekBar的滑动 改变的效果:

图示效果:




自定义View的代码:

package com.example.coustomviewdemo;

import android.R.color;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.view.View;

public class StatscsView extends View {

	public StatscsView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		
		init(context, null);
	}

	public StatscsView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init(context, attrs);
	}

//	坐标轴 轴线 画笔:
	private Paint axisLinePaint;
//	坐标轴水平内部 虚线画笔
	private Paint hLinePaint;
//	绘制文本的画笔
	private Paint titlePaint;
//	矩形画笔 柱状图的样式信息
	private Paint recPaint;
	private void init(Context context, AttributeSet attrs)
	{
		
		axisLinePaint = new Paint();
		hLinePaint = new Paint();
		titlePaint = new Paint();
		recPaint = new Paint();
		
		axisLinePaint.setColor(Color.DKGRAY);
		hLinePaint.setColor(Color.LTGRAY);
		titlePaint.setColor(Color.BLACK);
		
	}
	
	//7 条
	private int[] thisYear;
	
	//7 条
	private int[] lastYear;
	

	/**
	 * 跟新自身的数据 需要View子类重绘。
	 * 
	 * 主线程 刷新控件的时候调用:
	 * this.invalidate();  失效的意思。
	 * this.postInvalidate();  可以子线程 更新视图的方法调用。
	 * 
	 * */
	//updata this year data
	public void updateThisData(int[] thisData)
	{
		thisYear = thisData;
//		this.invalidate(); //失效的意思。
		this.postInvalidate();  //可以子线程 更新视图的方法调用。
	}
	
	//updata last year data
	public void updateLastData(int[] lastData)
	{
		lastYear = lastData;
//		this.invalidate(); //失效的意思。
		this.postInvalidate();  //可以子线程 更新视图的方法调用。
	}
	
	
	private String[] yTitlesStrings = 
			new String[]{"80000","60000","40000","20000","0"};
	
	private String[] xTitles = 
			new String[]{"1","2","3","4","5","6","7"};
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		
		int width = getWidth();
		int height = getHeight();
		
		// 1 绘制坐标线:
		canvas.drawLine(100, 10, 100, 320, axisLinePaint);
		
		canvas.drawLine(100, 320, width-10 , 320, axisLinePaint);
		
		// 2 绘制坐标内部的水平线
		
		int leftHeight = 300;// 左侧外周的 需要划分的高度:
		
		int hPerHeight = leftHeight/4;
		
		hLinePaint.setTextAlign(Align.CENTER);
		for(int i=0;i<4;i++)
		{
			canvas.drawLine(100, 20+i*hPerHeight, width-10, 20+i*hPerHeight, hLinePaint);
		}
		
		
		// 3 绘制 Y 周坐标
		
		FontMetrics metrics =titlePaint.getFontMetrics();
		int descent = (int)metrics.descent;
		titlePaint.setTextAlign(Align.RIGHT);
		for(int i=0;i<yTitlesStrings.length;i++)
		{
			canvas.drawText(yTitlesStrings[i], 80, 20+i*hPerHeight+descent, titlePaint);
		}
		
		// 4  绘制 X 周 做坐标
		
		int xAxisLength = width-110;
		int columCount = xTitles.length+1;
		int step = xAxisLength/columCount;
		
		for(int i=0;i<columCount-1;i++)
		{
			canvas.drawText(xTitles[i], 100+step*(i+1), 360 , titlePaint);
		}
		
		// 5 绘制矩形
		
		if(thisYear != null && thisYear.length >0)
		{
			int thisCount = thisYear.length;
			
			
			for(int i=0;i<thisCount;i++)
			{
				int value = thisYear[i];
				
				int num = 8 - value / 10000 ;
				
				
				recPaint.setColor(0xFF1078CF);
				
				Rect rect = new Rect();
				
				rect.left  = 100 + step * (i+1)  - 10;
				rect.right = 100 + step * (i+1)  + 10;
				
//				当前的相对高度:
				int rh = (leftHeight * num) / 8 ;
				
				rect.top = rh + 20;
				rect.bottom = 320 ;
				
				canvas.drawRect(rect, recPaint);
				
			}
		}
		
		
		if(lastYear != null && lastYear.length >0)
		{
			int thisCount = lastYear.length;
			
			
			for(int i=0;i<thisCount;i++)
			{
				int value = lastYear[i];
				
				int num = 8 - value / 10000 ;
				
				
				recPaint.setColor(0xFFAA1122);
				
				Rect rect = new Rect();
				
				rect.left  = 100 + step * (i+1)  - 10;
				rect.right = 100 + step * (i+1)  + 10;
				
//				当前的相对高度:
				int rh = (leftHeight * num) / 8 ;
				
				rect.top = rh + 20;
				rect.bottom = 320 ;
				
				canvas.drawRect(rect, recPaint);
				
			}
		}
		
		
		
		
	}
	

}

Activity:

package com.example.coustomviewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class StatscsActivity extends Activity implements
		OnSeekBarChangeListener {

	private SeekBar seekBar;

	private StatscsView statscsView;

	public StatscsActivity() {
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.sycts);

		seekBar = (SeekBar) this.findViewById(R.id.seekBar);

		statscsView = (StatscsView) this.findViewById(R.id.statscsView1);

		// seekerBar
		seekBar.setOnSeekBarChangeListener(this);

	}

	private int[] lastData0 = new int[] { 70000, 10000, 20000, 40000, 50000,
			80000, 40000 };
	private int[] thisData0 = new int[] { 40000, 10000, 10000, 20000, 30000,
			50000, 30000 };

	private int[] lastData1 = new int[] { 70000, 60000, 60000, 40000, 50000,
			80000, 80000 };
	private int[] thisData1 = new int[] { 40000, 30000, 30000, 20000, 30000,
			50000, 30000 };

	private int[] lastData2 = new int[] { 70000, 50000, 70000, 80000, 80000,
			80000, 70000 };
	private int[] thisData2 = new int[] { 40000, 10000, 40000, 40000, 30000,
			40000, 10000 };

	private int[] lastData3 = new int[] { 70000, 80000, 70000, 40000, 50000,
			80000, 40000 };
	private int[] thisData3 = new int[] { 10000, 10000, 10000, 20000, 30000,
			10000, 30000 };

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		// TODO Auto-generated method stub

		int cc = progress / 4;

		switch (cc) {
		case 0:
			statscsView.updateThisData(lastData0);
			statscsView.updateLastData(thisData0);

			break;
		case 1:
			statscsView.updateThisData(lastData1);
			statscsView.updateLastData(thisData1);

			break;
		case 2:
			statscsView.updateThisData(lastData2);
			statscsView.updateLastData(thisData2);
			
			break;
		case 3:
			statscsView.updateThisData(lastData3);
			statscsView.updateLastData(thisData3);

			break;

		default:
			break;
		}


	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		// TODO Auto-generated method stub

	}
}


main.xml

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

    
    <SeekBar 
        android:id="@+id/seekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:max="48"
        
        />
    
    <LinearLayout 
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:gravity="center"
        >
        
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="1"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="2"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="3"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="4"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="5"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="6"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="7"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="8"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="9"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="10"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="11"
            />
        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" android:gravity="center"
            android:text="12"
            />
        
        
    </LinearLayout>
    
    <com.example.coustomviewdemo.StatscsView
        android:id="@+id/statscsView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。