android自定义环形对比图(外环有类似进度条的旋转动画)
http://blog.****.net/u012483116/article/details/50635268
1.首先在res/values里创建一个attr.xml的文件。
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <declare-styleable name="AnswerChartView">
- <attr name="radius" format="dimension"/>
- <attr name="strokeWidth" format="dimension"/>
- <attr name="circleColor" format="color"/>
- <attr name="innerringColor" format="color"/>
- <attr name="outringColor" format="color"/>
- <attr name="textSize" format="dimension"/>
- </declare-styleable>
- </resources>
2.然后为自定义对比图View
- package com.jsle.ebag.answer.view;
- import com.jsle.ebag.answer.R;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- import android.graphics.RectF;
- import android.graphics.Paint.FontMetrics;
- import android.util.AttributeSet;
- import android.view.View;
- /**
- * 弧线对比图
- * @param
- * @return
- * @author LH
- * @data 2016年1月25日 下午6:17:34
- **/
- public class AnswerChartView extends View {
- // 圆画笔
- private Paint mCirclePaint;
- // 圆环画笔
- private Paint mRingPaint;
- // 百分数画笔
- private Paint mTextPaint;
- // 文本画笔
- private Paint mTextPaint2;
- // 里面圆颜色
- private int mCircleColor;
- // 里面弧颜色
- private int mInnerRingColor;
- // 外面弧颜色
- private int mOutRingColor;
- // 空白的圆半径
- private float mRadius;
- // 里面的弧半径
- private float mRingRadius;
- // 最外弧半径
- private float mRingRadius2;
- // 圆环的宽度
- private float mStrokeWidth;
- // 文本的中心x轴位置
- private int mXCenter;
- // 文本的中心y轴位置
- private int mYCenter;
- // 百分比文本的宽度
- private float mTxtWidth;
- // 描述文本的宽度
- private float mTxtWidth2;
- // 文本的高度
- private float mTxtHeight;
- // 百分数文本的大小
- private float mTxtSize;
- // 总成绩
- private int mTotalProgress = 100;
- // 个人的正确率
- private double mInnerProgress;
- // 班级的正确率
- private double mOutProgress;
- public AnswerChartView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initAttrs(context, attrs);
- initVariable();
- }
- private void initAttrs(Context context, AttributeSet attrs) {
- TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs,
- R.styleable.AnswerChartView, 0, 0);
- mRadius = typeArray.getDimension(R.styleable.AnswerChartView_radius, 80);
- mTxtSize=typeArray.getDimension(R.styleable.AnswerChartView_textSize, 20);
- mStrokeWidth = typeArray.getDimension(R.styleable.AnswerChartView_strokeWidth, 10);
- mCircleColor = typeArray.getColor(R.styleable.AnswerChartView_circleColor, 0xFFFFFFFF);
- mOutRingColor = typeArray.getColor(R.styleable.AnswerChartView_innerringColor, 0xFFFFFFFF);
- mInnerRingColor = typeArray.getColor(R.styleable.AnswerChartView_outringColor, 0xFFFFFFFF);
- mRingRadius = mRadius + mStrokeWidth / 2;
- mRingRadius2 = mRadius + mStrokeWidth/2*3;
- }
- private void initVariable() {
- mCirclePaint = new Paint();
- mCirclePaint.setAntiAlias(true);
- mCirclePaint.setStyle(Paint.Style.FILL);
- mRingPaint = new Paint();
- mRingPaint.setAntiAlias(true);
- mRingPaint.setColor(mInnerRingColor);
- mRingPaint.setStyle(Paint.Style.STROKE);
- mRingPaint.setStrokeWidth(mStrokeWidth);
- mTextPaint = new Paint();
- mTextPaint.setAntiAlias(true);
- mTextPaint.setStyle(Paint.Style.FILL);
- mTextPaint.setARGB(255, 32, 207, 152);
- mTextPaint.setTextSize(mTxtSize);
- mTextPaint2 = new Paint();
- mTextPaint2.setAntiAlias(true);
- mTextPaint2.setStyle(Paint.Style.FILL);
- mTextPaint2.setARGB(255, 0, 0, 0);
- mTextPaint2.setTextSize(20);
- FontMetrics fm = mTextPaint.getFontMetrics();
- mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- mXCenter = getWidth() / 2;
- mYCenter = getHeight() / 2;
- mCirclePaint.setColor(getResources().getColor(R.color.gray));
- canvas.drawCircle(mXCenter,mYCenter, mRadius + mStrokeWidth*2, mCirclePaint);
- RectF oval1 = new RectF();
- oval1.left = (mXCenter - mRingRadius);
- oval1.top = (mYCenter - mRingRadius);
- oval1.right = mRingRadius * 2 + (mXCenter - mRingRadius);
- oval1.bottom = mRingRadius * 2 + (mYCenter - mRingRadius);
- mRingPaint.setColor(mOutRingColor);
- canvas.drawArc(oval1, -90, ((float)mOutProgress / mTotalProgress) * 360, false, mRingPaint);
- mCirclePaint.setColor(mCircleColor);
- canvas.drawCircle(mXCenter, mYCenter, mRadius, mCirclePaint);
- if (mInnerProgress > 0 ) {
- RectF oval = new RectF();
- oval.left = (mXCenter - mRingRadius2);
- oval.top = (mYCenter - mRingRadius2);
- oval.right = mRingRadius2 * 2 + (mXCenter - mRingRadius2);
- oval.bottom = mRingRadius2 * 2 + (mYCenter - mRingRadius2);
- mRingPaint.setColor(mInnerRingColor);
- canvas.drawArc(oval, -90, ((float)mInnerProgress / mTotalProgress) * 360, false, mRingPaint); //
- // canvas.drawCircle(mXCenter, mYCenter, mRadius + mStrokeWidth / 2, mRingPaint);
- String txt = mInnerProgress + "%";
- String txt2 = "正确率";
- mTxtWidth = mTextPaint.measureText(txt, 0, txt.length());
- mTxtWidth2 = mTextPaint2.measureText(txt2, 0, txt2.length());
- canvas.drawText(txt, mXCenter - mTxtWidth / 2, mYCenter+mTxtWidth / 8, mTextPaint);
- canvas.drawText(txt2 ,mXCenter - mTxtWidth2 / 2, mYCenter + mTxtWidth / 2, mTextPaint2);
- }else if(mInnerProgress==0){
- String txt = mInnerProgress + "%";
- String txt2 = "正确率";
- mTxtWidth = mTextPaint.measureText(txt, 0, txt.length());
- mTxtWidth2 = mTextPaint2.measureText(txt2, 0, txt2.length());
- canvas.drawText(txt, mXCenter - mTxtWidth / 2, mYCenter+mTxtWidth / 8, mTextPaint);
- canvas.drawText(txt2 ,mXCenter - mTxtWidth2 / 2, mYCenter + mTxtWidth / 2, mTextPaint2);
- }
- }
- public void setOutProgress(double progress){
- mOutProgress=progress;
- }
- public void setInnerProgress(double progress) {
- mInnerProgress = progress;
- // invalidate();
- postInvalidate();
- }
- }
3.使用自定义View
- <com.jsle.ebag.answer.view.AnswerChartView
- android:id="@+id/tasks_view"
- android:layout_width="160dp"
- android:layout_height="160dp"
- android:layout_centerHorizontal="true"
- tc:circleColor="@color/circle_color"
- tc:innerringColor="@color/dark_yellow"
- tc:outringColor="@color/green"
- tc:radius="60dip"
- tc:strokeWidth="6dip"
- tc:textSize="32sp" />
4.最后可已在AnswerChartActivity中设置内环和外环的百分比和属性
- </pre><pre name="code" class="java">package com.jsle.ebag.answer.activity;
- import java.text.DecimalFormat;
- import com.jsle.ebag.answer.R;
- import com.jsle.ebag.answer.R.layout;
- import com.jsle.ebag.answer.view.AnswerChartView;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- public class AnswerChartActivity extends BaseActivity implements OnClickListener {
- private AnswerChartView mTasksView;
- private double mAccuracy;//个人的正确率
- private double cAccuracy;//班级的正确率
- private double mCurrentProgress;
- private LinearLayout btn_black;
- private TextView tv_title,tv_subjectcount,tv_submit,tv_accuracy;
- private String title;
- private double maccuracy,caccuracy;
- private int subjectcount,submit;
- @Override
- protected int getID() {
- // TODO Auto-generated method stub
- return R.id.Activity_ID_AnswerChart;
- }
- @Override
- protected String getTag() {
- // TODO Auto-generated method stub
- return "AnswerChart_Acitivity";
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_answer_chart);
- btn_black=(LinearLayout) findViewById(R.id.btn_black);
- tv_title=(TextView) findViewById(R.id.tv_title);
- tv_subjectcount=(TextView) findViewById(R.id.tv_subjectcount);
- tv_submit=(TextView) findViewById(R.id.tv_submit);
- tv_accuracy=(TextView) findViewById(R.id.tv_accuracy);
- btn_black.setOnClickListener(this);
- getData();
- initVariable();
- initView();
- new Thread(new ProgressRunable()).start();
- }
- private void getData() {
- // TODO Auto-generated method stub
- Intent intent = getIntent();
- title=intent.getStringExtra("title");
- maccuracy = intent.getDoubleExtra("maccuracy", 0);
- caccuracy = intent.getDoubleExtra("caccuracy", 0);
- subjectcount=intent.getIntExtra("subjectcount", 0);
- submit=intent.getIntExtra("submit", 0);
- }
- private void initVariable() {
- tv_title.setText(title);
- tv_subjectcount.setText("共"+subjectcount+"道题");
- tv_submit.setText(submit+"");
- tv_accuracy.setText(caccuracy+"%");
- mAccuracy =maccuracy;
- cAccuracy=caccuracy;
- mCurrentProgress = 0;
- }
- private void initView() {
- mTasksView = (AnswerChartView) findViewById(R.id.tasks_view);
- mTasksView.setOutProgress(cAccuracy);
- }
- /**
- *进度动画效果
- * @author LH
- * @data 2016年1月29日 下午3:43:31
- **/
- class ProgressRunable implements Runnable {
- @Override
- public void run() {
- while (mCurrentProgress < mAccuracy) {
- mCurrentProgress += 1;
- if(mCurrentProgress>mAccuracy){
- mCurrentProgress=mAccuracy;
- }
- mTasksView.setInnerProgress(mCurrentProgress);
- try {
- Thread.sleep(15);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch (v.getId()) {
- case R.id.btn_black:
- finish();
- break;
- default:
- break;
- }
- }
- }
- 顶
- 1
- 踩
- 0
1.首先在res/values里创建一个attr.xml的文件。
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <declare-styleable name="AnswerChartView">
- <attr name="radius" format="dimension"/>
- <attr name="strokeWidth" format="dimension"/>
- <attr name="circleColor" format="color"/>
- <attr name="innerringColor" format="color"/>
- <attr name="outringColor" format="color"/>
- <attr name="textSize" format="dimension"/>
- </declare-styleable>
- </resources>
2.然后为自定义对比图View
- package com.jsle.ebag.answer.view;
- import com.jsle.ebag.answer.R;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- import android.graphics.RectF;
- import android.graphics.Paint.FontMetrics;
- import android.util.AttributeSet;
- import android.view.View;
- /**
- * 弧线对比图
- * @param
- * @return
- * @author LH
- * @data 2016年1月25日 下午6:17:34
- **/
- public class AnswerChartView extends View {
- // 圆画笔
- private Paint mCirclePaint;
- // 圆环画笔
- private Paint mRingPaint;
- // 百分数画笔
- private Paint mTextPaint;
- // 文本画笔
- private Paint mTextPaint2;
- // 里面圆颜色
- private int mCircleColor;
- // 里面弧颜色
- private int mInnerRingColor;
- // 外面弧颜色
- private int mOutRingColor;
- // 空白的圆半径
- private float mRadius;
- // 里面的弧半径
- private float mRingRadius;
- // 最外弧半径
- private float mRingRadius2;
- // 圆环的宽度
- private float mStrokeWidth;
- // 文本的中心x轴位置
- private int mXCenter;
- // 文本的中心y轴位置
- private int mYCenter;
- // 百分比文本的宽度
- private float mTxtWidth;
- // 描述文本的宽度
- private float mTxtWidth2;
- // 文本的高度
- private float mTxtHeight;
- // 百分数文本的大小
- private float mTxtSize;
- // 总成绩
- private int mTotalProgress = 100;
- // 个人的正确率
- private double mInnerProgress;
- // 班级的正确率
- private double mOutProgress;
- public AnswerChartView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initAttrs(context, attrs);
- initVariable();
- }
- private void initAttrs(Context context, AttributeSet attrs) {
- TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs,
- R.styleable.AnswerChartView, 0, 0);
- mRadius = typeArray.getDimension(R.styleable.AnswerChartView_radius, 80);
- mTxtSize=typeArray.getDimension(R.styleable.AnswerChartView_textSize, 20);
- mStrokeWidth = typeArray.getDimension(R.styleable.AnswerChartView_strokeWidth, 10);
- mCircleColor = typeArray.getColor(R.styleable.AnswerChartView_circleColor, 0xFFFFFFFF);
- mOutRingColor = typeArray.getColor(R.styleable.AnswerChartView_innerringColor, 0xFFFFFFFF);
- mInnerRingColor = typeArray.getColor(R.styleable.AnswerChartView_outringColor, 0xFFFFFFFF);
- mRingRadius = mRadius + mStrokeWidth / 2;
- mRingRadius2 = mRadius + mStrokeWidth/2*3;
- }
- private void initVariable() {
- mCirclePaint = new Paint();
- mCirclePaint.setAntiAlias(true);
- mCirclePaint.setStyle(Paint.Style.FILL);
- mRingPaint = new Paint();
- mRingPaint.setAntiAlias(true);
- mRingPaint.setColor(mInnerRingColor);
- mRingPaint.setStyle(Paint.Style.STROKE);
- mRingPaint.setStrokeWidth(mStrokeWidth);
- mTextPaint = new Paint();
- mTextPaint.setAntiAlias(true);
- mTextPaint.setStyle(Paint.Style.FILL);
- mTextPaint.setARGB(255, 32, 207, 152);
- mTextPaint.setTextSize(mTxtSize);
- mTextPaint2 = new Paint();
- mTextPaint2.setAntiAlias(true);
- mTextPaint2.setStyle(Paint.Style.FILL);
- mTextPaint2.setARGB(255, 0, 0, 0);
- mTextPaint2.setTextSize(20);
- FontMetrics fm = mTextPaint.getFontMetrics();
- mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- mXCenter = getWidth() / 2;
- mYCenter = getHeight() / 2;
- mCirclePaint.setColor(getResources().getColor(R.color.gray));
- canvas.drawCircle(mXCenter,mYCenter, mRadius + mStrokeWidth*2, mCirclePaint);
- RectF oval1 = new RectF();
- oval1.left = (mXCenter - mRingRadius);
- oval1.top = (mYCenter - mRingRadius);
- oval1.right = mRingRadius * 2 + (mXCenter - mRingRadius);
- oval1.bottom = mRingRadius * 2 + (mYCenter - mRingRadius);
- mRingPaint.setColor(mOutRingColor);
- canvas.drawArc(oval1, -90, ((float)mOutProgress / mTotalProgress) * 360, false, mRingPaint);
- mCirclePaint.setColor(mCircleColor);
- canvas.drawCircle(mXCenter, mYCenter, mRadius, mCirclePaint);
- if (mInnerProgress > 0 ) {
- RectF oval = new RectF();
- oval.left = (mXCenter - mRingRadius2);
- oval.top = (mYCenter - mRingRadius2);
- oval.right = mRingRadius2 * 2 + (mXCenter - mRingRadius2);
- oval.bottom = mRingRadius2 * 2 + (mYCenter - mRingRadius2);
- mRingPaint.setColor(mInnerRingColor);
- canvas.drawArc(oval, -90, ((float)mInnerProgress / mTotalProgress) * 360, false, mRingPaint); //
- // canvas.drawCircle(mXCenter, mYCenter, mRadius + mStrokeWidth / 2, mRingPaint);
- String txt = mInnerProgress + "%";
- String txt2 = "正确率";
- mTxtWidth = mTextPaint.measureText(txt, 0, txt.length());
- mTxtWidth2 = mTextPaint2.measureText(txt2, 0, txt2.length());
- canvas.drawText(txt, mXCenter - mTxtWidth / 2, mYCenter+mTxtWidth / 8, mTextPaint);
- canvas.drawText(txt2 ,mXCenter - mTxtWidth2 / 2, mYCenter + mTxtWidth / 2, mTextPaint2);
- }else if(mInnerProgress==0){
- String txt = mInnerProgress + "%";
- String txt2 = "正确率";
- mTxtWidth = mTextPaint.measureText(txt, 0, txt.length());
- mTxtWidth2 = mTextPaint2.measureText(txt2, 0, txt2.length());
- canvas.drawText(txt, mXCenter - mTxtWidth / 2, mYCenter+mTxtWidth / 8, mTextPaint);
- canvas.drawText(txt2 ,mXCenter - mTxtWidth2 / 2, mYCenter + mTxtWidth / 2, mTextPaint2);
- }
- }
- public void setOutProgress(double progress){
- mOutProgress=progress;
- }
- public void setInnerProgress(double progress) {
- mInnerProgress = progress;
- // invalidate();
- postInvalidate();
- }
- }
3.使用自定义View
- <com.jsle.ebag.answer.view.AnswerChartView
- android:id="@+id/tasks_view"
- android:layout_width="160dp"
- android:layout_height="160dp"
- android:layout_centerHorizontal="true"
- tc:circleColor="@color/circle_color"
- tc:innerringColor="@color/dark_yellow"
- tc:outringColor="@color/green"
- tc:radius="60dip"
- tc:strokeWidth="6dip"
- tc:textSize="32sp" />
4.最后可已在AnswerChartActivity中设置内环和外环的百分比和属性
- </pre><pre name="code" class="java">package com.jsle.ebag.answer.activity;
- import java.text.DecimalFormat;
- import com.jsle.ebag.answer.R;
- import com.jsle.ebag.answer.R.layout;
- import com.jsle.ebag.answer.view.AnswerChartView;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- public class AnswerChartActivity extends BaseActivity implements OnClickListener {
- private AnswerChartView mTasksView;
- private double mAccuracy;//个人的正确率
- private double cAccuracy;//班级的正确率
- private double mCurrentProgress;
- private LinearLayout btn_black;
- private TextView tv_title,tv_subjectcount,tv_submit,tv_accuracy;
- private String title;
- private double maccuracy,caccuracy;
- private int subjectcount,submit;
- @Override
- protected int getID() {
- // TODO Auto-generated method stub
- return R.id.Activity_ID_AnswerChart;
- }
- @Override
- protected String getTag() {
- // TODO Auto-generated method stub
- return "AnswerChart_Acitivity";
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_answer_chart);
- btn_black=(LinearLayout) findViewById(R.id.btn_black);
- tv_title=(TextView) findViewById(R.id.tv_title);
- tv_subjectcount=(TextView) findViewById(R.id.tv_subjectcount);
- tv_submit=(TextView) findViewById(R.id.tv_submit);
- tv_accuracy=(TextView) findViewById(R.id.tv_accuracy);
- btn_black.setOnClickListener(this);
- getData();
- initVariable();
- initView();
- new Thread(new ProgressRunable()).start();
- }
- private void getData() {
- // TODO Auto-generated method stub
- Intent intent = getIntent();
- title=intent.getStringExtra("title");
- maccuracy = intent.getDoubleExtra("maccuracy", 0);
- caccuracy = intent.getDoubleExtra("caccuracy", 0);
- subjectcount=intent.getIntExtra("subjectcount", 0);
- submit=intent.getIntExtra("submit", 0);
- }
- private void initVariable() {
- tv_title.setText(title);
- tv_subjectcount.setText("共"+subjectcount+"道题");
- tv_submit.setText(submit+"");
- tv_accuracy.setText(caccuracy+"%");
- mAccuracy =maccuracy;
- cAccuracy=caccuracy;
- mCurrentProgress = 0;
- }
- private void initView() {
- mTasksView = (AnswerChartView) findViewById(R.id.tasks_view);
- mTasksView.setOutProgress(cAccuracy);
- }
- /**
- *进度动画效果
- * @author LH
- * @data 2016年1月29日 下午3:43:31
- **/
- class ProgressRunable implements Runnable {
- @Override
- public void run() {
- while (mCurrentProgress < mAccuracy) {
- mCurrentProgress += 1;
- if(mCurrentProgress>mAccuracy){
- mCurrentProgress=mAccuracy;
- }
- mTasksView.setInnerProgress(mCurrentProgress);
- try {
- Thread.sleep(15);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch (v.getId()) {
- case R.id.btn_black:
- finish();
- break;
- default:
- break;
- }
- }
- }
- 顶
- 1
- 踩
- 0