您的位置:首页 > 移动开发 > Android开发

android自定义环形对比图(外环有类似进度条的旋转动画)

2017-05-08 10:26 579 查看
http://blog.csdn.net/u012483116/article/details/50635268



1.首先在res/values里创建一个attr.xml的文件。

[html] view
plain copy

<?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

[java] view
plain copy

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

[html] view
plain copy

<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中设置内环和外环的百分比和属性

[java] view
plain copy

</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

下一篇android用数组保存输出流的数据包的问题(最后等到的所有的都变成最后一个包)



1.首先在res/values里创建一个attr.xml的文件。

[html] view
plain copy

<?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

[java] view
plain copy

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

[html] view
plain copy

<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中设置内环和外环的百分比和属性

[java] view
plain copy

</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

下一篇android用数组保存输出流的数据包的问题(最后等到的所有的都变成最后一个包)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: