柱状图

效果图:




柱状图的效果是从下往上逐渐增长,并且每个柱状图是可以响应点击事件的。


package com.example.wavedemo;

import java.util.ArrayList;
import java.util.List;

import com.example.wavedemo.BarPic5.OnClickListener;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity3 extends Activity {
	
	private BarPic5 barPic;
	private List<BarBean> lists;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main3);
		barPic=(BarPic5) findViewById(R.id.barpic);
		lists=new ArrayList<BarBean>();
		lists.add(new BarBean("高流动性","5%",100,5));
		lists.add(new BarBean("固定收益","1%",100,1));
		lists.add(new BarBean("浮动收益","50%",100,50));
		lists.add(new BarBean("另类投资","100%",100,100));
		barPic.setData(lists);
		new Thread(barPic).start();
		barPic.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onclick(int i) {
				Toast.makeText(MainActivity3.this, lists.get(i).getDescription()+(lists.get(i).isFlag()?"选中":"取消选中"), Toast.LENGTH_SHORT).show();
			}
		});

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		return super.onOptionsItemSelected(item);
	}
	
	

}



package com.example.wavedemo;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class BarPic5 extends View implements Runnable {
	private Paint linePaint;// 线条画笔
	private int width;// 控件的宽高
	private int height;
	private int perWidth;// 每个柱状图的宽度
	private int space = 10;// 柱状图之间的间距
	private int num = 7;// 线的条数
	private int lineSpace;// 线条之间的间隔
	private int startX, startY, endX, endY;// 记录线条的位置
	private Paint barPaint;
	private int startPadding = 20;// 要绘制的柱状图距离边界起始结束距离
	private int endPadding = 20;
	private int lineStartX, lineEndX, lineStartY, lineEndY;// 记录柱状图位置
	private int maskStartX, maskEndX, maskStartY, maskEndY;// 记录遮罩位置
	private TextPaint textPaint;
	private Paint maskPaint;// 遮罩画笔
	private FontMetrics metrics;// 字体测量
	private FontMetrics dataMetrics;
	private int baseline;
	private TextPaint dataPaint;// 绘制数据画笔
	private int dataHeight;
	private List<BarBean> lists;
	private int maskHeight;//遮罩高度
	private OnClickListener listener;

	public BarPic5(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public BarPic5(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public BarPic5(Context context) {
		super(context);
		init();
	}

	public void init() {
		linePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		linePaint.setColor(Color.parseColor("#bebebe"));
		linePaint.setStrokeWidth(2);

		barPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

		textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		textPaint.setColor(Color.parseColor("#ffffff"));
		textPaint.setTextSize(50);
		textPaint.setTextAlign(Align.CENTER);
		metrics = textPaint.getFontMetrics();
		maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

		dataPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		dataPaint.setTextSize(40);
		dataPaint.setTextAlign(Align.CENTER);
		dataMetrics = dataPaint.getFontMetrics();
	}

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

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		width = w;
		height = h;
		maskHeight=(int) (7.0 / 8 * height);
		perWidth = (width - getPaddingLeft() - getPaddingRight() - 3 * space
				- startPadding - endPadding) / 4;
		if (num >= 2) {
			lineSpace = height / (num - 1);
		}
		barPaint.setStrokeWidth(perWidth);
		maskPaint.setStrokeWidth(perWidth);
		baseline = (int) ((-metrics.ascent + metrics.descent) / 2);
		dataHeight = (int) (-dataMetrics.ascent + dataMetrics.descent);
		
		lineEndY=maskHeight;
		
		if(lists!=null)
		{
			for(int i=0;i<lists.size();i++)
			{
				lists.get(i).setHeight(maskHeight-(lists.get(i).getActualHeight()*(maskHeight-dataHeight-dataHeight))/lists.get(i).getTotalHeight());
			}
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(Color.parseColor("#efefef"));
		if (lineSpace > 0)// 需要画线,初始为0
		{
			startX = getPaddingLeft();
			endX = width - getPaddingRight();
			startY=0;
			endY=0;
			for (int i = 0; i < num; i++) {
				canvas.drawLine(startX, startY, endX, endY, linePaint);
				startY += lineSpace;
				endY += lineSpace;
			}
		}
		
		
		lineStartX = lineEndX = getPaddingLeft() + startPadding + perWidth / 2;
		lineStartY = height;
		maskStartX = maskEndX = lineStartX;
		maskStartY = height;
		maskEndY = maskHeight;
		if(lists.get(0).isFlag())
		{
			barPaint.setColor(Color.parseColor("#089ae9"));
		}
		else
		{
		    barPaint.setColor(Color.parseColor("#6bc1f2"));
		}
		canvas.drawLine(lineStartX, lineStartY, lineEndX,
				lineEndY >= lists.get(0).getHeight() ? lineEndY : lists.get(0).getHeight(), barPaint);
		maskPaint.setColor(Color.parseColor("#089ae9"));
		canvas.drawLine(maskStartX, maskStartY, maskEndX, maskEndY, maskPaint);
		canvas.drawText(lists.get(0).getDescription(), lineStartX, lineStartY - baseline, textPaint);
		dataPaint.setColor(Color.parseColor("#6bc1f2"));
		canvas.drawText(lists.get(0).getData(), lineStartX, (lineEndY >= lists.get(0).getHeight() ? lineEndY : lists.get(0).getHeight()) - dataHeight, dataPaint);
		lists.get(0).setLeftX(lineStartX-perWidth/2);
		lists.get(0).setRightX(lineStartX+perWidth/2);
         ///
		
		
		
		lineStartX = lineEndX = getPaddingLeft() + startPadding + perWidth / 2
				+ space + perWidth;
		lineStartY = height;
		maskStartX = maskEndX = lineStartX;
		if(lists.get(1).isFlag())
		{
			barPaint.setColor(Color.parseColor("#63ae4e"));
		}
		else
		{
		    barPaint.setColor(Color.parseColor("#97d573"));
		}
		canvas.drawLine(lineStartX, lineStartY, lineEndX,
				lineEndY >= lists.get(1).getHeight() ? lineEndY : lists.get(1).getHeight(), barPaint);
		maskPaint.setColor(Color.parseColor("#63ae4e"));
		canvas.drawLine(maskStartX, maskStartY, maskEndX, maskEndY, maskPaint);
		canvas.drawText(lists.get(1).getDescription(), lineStartX, lineStartY - baseline, textPaint);
		dataPaint.setColor(Color.parseColor("#97d573"));
		canvas.drawText(lists.get(1).getData(), lineStartX, (lineEndY >= lists.get(1).getHeight() ? lineEndY : lists.get(1).getHeight()) - dataHeight, dataPaint);
		lists.get(1).setLeftX(lineStartX-perWidth/2);
		lists.get(1).setRightX(lineStartX+perWidth/2);
        ///

		
		
		lineStartX = lineEndX = getPaddingLeft() + startPadding + perWidth / 2
				+ space + perWidth + space + perWidth;
		lineStartY = height;
		maskStartX = maskEndX = lineStartX;
		if(lists.get(2).isFlag())
		{
			barPaint.setColor(Color.parseColor("#e99b39"));
		}
		else
		{
		    barPaint.setColor(Color.parseColor("#fec57b"));
		}

		canvas.drawLine(lineStartX, lineStartY, lineEndX,
				lineEndY >= lists.get(2).getHeight() ? lineEndY : lists.get(2).getHeight(), barPaint);
		maskPaint.setColor(Color.parseColor("#e99b39"));
		canvas.drawLine(maskStartX, maskStartY, maskEndX, maskEndY, maskPaint);
		canvas.drawText(lists.get(2).getDescription(), lineStartX, lineStartY - baseline, textPaint);
		dataPaint.setColor(Color.parseColor("#fec57b"));
		canvas.drawText(lists.get(2).getData(), lineStartX, (lineEndY >= lists.get(2).getHeight() ? lineEndY : lists.get(2).getHeight()) - dataHeight, dataPaint);
		lists.get(2).setLeftX(lineStartX-perWidth/2);
		lists.get(2).setRightX(lineStartX+perWidth/2);
        ///

		
		
		lineStartX = lineEndX = getPaddingLeft() + startPadding + perWidth / 2
				+ space + perWidth + space + perWidth + space + perWidth;
		lineStartY = height;
		maskStartX = maskEndX = lineStartX;
		if(lists.get(3).isFlag())
		{
			barPaint.setColor(Color.parseColor("#e65353"));
		}
		else
		{
		    barPaint.setColor(Color.parseColor("#ff8989"));
		}

		canvas.drawLine(lineStartX, lineStartY, lineEndX,
				lineEndY >= lists.get(3).getHeight() ? lineEndY : lists.get(3).getHeight(), barPaint);
		maskPaint.setColor(Color.parseColor("#e65353"));
		canvas.drawLine(maskStartX, maskStartY, maskEndX, maskEndY, maskPaint);
		canvas.drawText(lists.get(3).getDescription(), lineStartX, lineStartY - baseline, textPaint);
		dataPaint.setColor(Color.parseColor("#ff8989"));
		canvas.drawText(lists.get(3).getData(), lineStartX, (lineEndY >= lists.get(3).getHeight() ? lineEndY : lists.get(3).getHeight()) - dataHeight, dataPaint);
		lists.get(3).setLeftX(lineStartX-perWidth/2);
		lists.get(3).setRightX(lineStartX+perWidth/2);
		super.onDraw(canvas);
	}

	@Override
	public void run() {

		while (true) {
			try {
				Thread.currentThread().sleep(10);
				lineEndY-=2;
				postInvalidate();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
	/**
	 * 传递数据,根据数据绘制柱状图
	 * @param lists
	 */
	 public void setData(List<BarBean> lists)
	 {
		 if(lists.size()!=4)
		 {
			 throw new IllegalArgumentException("集合大小应该为4");
		 }
		 this.lists=lists;
		 init();
		 invalidate();
	 }
	 
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			int x=(int) event.getX();
			int y=(int) event.getY();
			if(lists!=null)
			{
				for(int i=0;i<lists.size();i++)
				{
					if(lists.get(i).getLeftX()<x&&x<lists.get(i).getRightX()&&y>lists.get(i).getHeight()&&y<maskHeight)
					{
						lists.get(i).setFlag(!lists.get(i).isFlag());
						for(int j=0;j<lists.size();j++)
						{
							if(j!=i)
							{
								lists.get(j).setFlag(false);
							}
						}
						if(listener!=null)
						{
							listener.onclick(i);
						}
						invalidate();
						break;
					}
				}
			}
			break;

		default:
			break;
		}
		return super.onTouchEvent(event);
	}
	
	public void setOnClickListener(OnClickListener listener)
	{
		this.listener=listener;
	}
	
	public interface  OnClickListener
	{
		void onclick(int i);
	}

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <com.example.wavedemo.BarPic5
        android:id="@+id/barpic"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:layout_width="match_parent"
        android:layout_height="270dp"
       
         />

</RelativeLayout>

package com.example.wavedemo;

import java.io.Serializable;

public class BarBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String description;// 描述字体
	private String data;// 柱状图上面的数据
	private int totalHeight;// 控件height所对应的data
	private int actualHeight;// 柱状图height所对应的data
	private int height;//柱状图实际height
	private boolean flag;//记录是不是点击状态
	private int leftX,rightX,topY;//记录左右上边距

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}

	public int getTotalHeight() {
		return totalHeight;
	}

	public void setTotalHeight(int totalHeight) {
		this.totalHeight = totalHeight;
	}

	public int getActualHeight() {
		return actualHeight;
	}

	public void setActualHeight(int actualHeight) {
		this.actualHeight = actualHeight;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}
	

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	
	


	public int getLeftX() {
		return leftX;
	}

	public void setLeftX(int leftX) {
		this.leftX = leftX;
	}

	public int getRightX() {
		return rightX;
	}

	public void setRightX(int rightX) {
		this.rightX = rightX;
	}

	public int getTopY() {
		return topY;
	}

	public void setTopY(int topY) {
		this.topY = topY;
	}


	@Override
	public String toString() {
		return "BarBean [description=" + description + ", data=" + data
				+ ", totalHeight=" + totalHeight + ", actualHeight="
				+ actualHeight + ", height=" + height + ", flag=" + flag
				+ ", leftX=" + leftX + ", rightX=" + rightX + ", topY=" + topY
				+ "]";
	}

	public BarBean(String description, String data, int totalHeight,
			int actualHeight) {
		super();
		this.description = description;
		this.data = data;
		this.totalHeight = totalHeight;
		this.actualHeight = actualHeight;
	}
	
	
	

}


如果需要自定义属性的话:


TypedArray types = context.obtainStyledAttributes(attrs, 
                R.styleable.barPic); 
        final int count = types.getIndexCount(); 
        Log.e("abc", count+"");
        for (int i = 0; i < count; ++i) { 
            int attr = types.getIndex(i); 
            switch (attr) { 
            case R.styleable.barPic_space: 
                space = (int) types.getDimension(attr, 10); 
                break; 
            case R.styleable.barPic_num: 
                num = types.getInteger(attr, 7); 
                break; 
            case R.styleable.barPic_startpadding: 
                startPadding = (int) types.getDimension(attr, 20); 
                break; 
            case R.styleable.barPic_endpadding: 
                endPadding = (int) types.getDimension(attr, 20); 
                break; 
            } 
        } 
        types.recycle(); 
	init();


attrs.xml文件

<resources>

    <declare-styleable name="barPic">
        <attr name="space" format="dimension" />
        <attr name="num" format="integer" />
        <attr name="startpadding" format="dimension" />
        <attr name="endpadding" format="dimension" />
    </declare-styleable>

</resources>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:haha="http://schemas.android.com/apk/res/com.example.wavedemo"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <com.example.wavedemo.BarPic
        android:id="@+id/barpic"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:layout_width="match_parent"
        android:layout_height="270dp"
        haha:num="3"
        haha:space="5dp"
        haha:startpadding="5dp"
        haha:endpadding="5dp"
         />

</RelativeLayout>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值