Android - 自定义控件(五)

自定义Android统计图表
本文介绍了一种在Android应用中自定义统计图表的方法,通过复写onDraw方法并使用Canvas绘制不同颜色区域来表现数据占比,同时实现了顺时针动画效果。

很多时候,Android提供的控件不能满足我们所需要的显示效果,就需要复写onDraw方法,使用canvas等进行绘制,假设进入一个界面时,需要展示某三个项目的收入所占的比重,并且需要一个从顶部开始顺时针方向绘制的动画效果,下边是这个统计图案在显示过程中的截图:

很明显,这个时候,就需要通过绘制的方式来自定义控件了,代码比较简单,直接上:

自定义的IncomeDistributionView:

public class IncomeDistributionView extends View {
	private Paint mPaint= null;
	private RectF mRectF;
	private int paintWidth;
	private int drawFlag = 0;
	private int oneRadian;
	private int twoRadian;
	 
	public IncomeDistributionView(Context context) {
		super(context);
	}
	public IncomeDistributionView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initPaint();
	}
	private void initPaint() {
		//统一设置画笔的宽度和样式
		mPaint= new Paint();
		paintWidth = dip2px(getContext(), 24);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(paintWidth);
		mRectF = new RectF(dip2px(getContext(), 12), dip2px(getContext(), 12),
				dip2px(getContext(), 218), dip2px(getContext(), 218));
	}
	public IncomeDistributionView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
	@SuppressLint("WrongCall")
	@Override
	protected void onDraw(final Canvas canvas) {
		super.onDraw(canvas);
		if(drawFlag>=0 && drawFlag<oneRadian){
			mPaint.setColor(getResources().getColor(R.color.total_order_image_consulting));// 设置颜色 
			canvas.drawArc(mRectF, 270, drawFlag, false, mPaint);
		}else if(drawFlag>=oneRadian && drawFlag <twoRadian){
			mPaint.setColor(getResources().getColor(R.color.total_order_image_consulting));
			canvas.drawArc(mRectF, 270, oneRadian, false, mPaint);
			mPaint.setColor(getResources().getColor(R.color.total_order_telephone_consultation));
			//此处的 270+oneRadian 是临时写的,这是不准确的,需要考虑 这个值大于360的情况
			canvas.drawArc(mRectF, 270+oneRadian, drawFlag-oneRadian, false, mPaint);
		}else if(drawFlag>=twoRadian && drawFlag <=360){
			mPaint.setColor(getResources().getColor(R.color.total_order_image_consulting));
			canvas.drawArc(mRectF, 270, oneRadian, false, mPaint);
			mPaint.setColor(getResources().getColor(R.color.total_order_telephone_consultation));
			canvas.drawArc(mRectF, 270+oneRadian, twoRadian-oneRadian, false, mPaint);
			mPaint.setColor(getResources().getColor(R.color.total_order_video_consultation));
			canvas.drawArc(mRectF,270+twoRadian-360, drawFlag-twoRadian, false, mPaint);
		}
	}
	/**
	 * 重绘过程中的偏移角度
	 * @param i
	 */
	public void startDraw(int i) {
		drawFlag = i;
	}
	/**
	 * 设置绘制起点角度
	 * @param radianOne
	 * @param radianTwo
	 */
	public void setDemarcation(int radianOne,int radianTwo){
		oneRadian = radianOne;
		twoRadian = radianTwo;
	}
	public static int dip2px(Context context, float dipValue) {
		float ret = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, context.getResources().getDisplayMetrics());
		return (int) (ret + 0.5f);
	}
}

需要使用自定义view的MainActivity:

public class MainActivity extends Activity {
	private  IncomeDistributionView mIncomeDistributionView=  null;
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			mIncomeDistributionView.startDraw(msg.what);
			mIncomeDistributionView.invalidate();
		};
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		findView();
	}
	private void findView() {
		mIncomeDistributionView = (IncomeDistributionView) findViewById(R.id.view_income_distribution);
		//该逻辑只为演示效果,作用是得到两个百分比数字,进而得到对应的弧度值
		int radianOne = 72;
		int radianTwo = 252;
		//则
		mIncomeDistributionView.setDemarcation(radianOne, radianTwo);
		new Thread(){
			public void run() {
				int i = 0;
				try {
					sleep(200);
					while(i<=360){
						mHandler.sendEmptyMessage(i);
						i+=1;
						sleep(3);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
}

在activity_main.xml文件中进行引入:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.hwgt.statisticalchart.MainActivity" >
	<com.hwgt.statisticalchart.view.IncomeDistributionView
		android:id="@+id/view_income_distribution"
		android:layout_width="230dp"
		android:layout_height="230dp"
		android:layout_marginTop="23dp"
		android:layout_centerHorizontal="true"
		android:layout_alignParentTop="true"/>
</RelativeLayout>

逻辑还是比较简单的,首先是设定统计图案中三个颜色区域的分界点,然后,处理handler发送的消息调用invalidate方法进行重绘。

 

转载于:https://www.cnblogs.com/hwgt/p/5420684.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值