是时候拿起笔画一个自定义控件了————————————
废话不多讲,先上效果图:↓↓↓
正式开始我们的自定义工作。
第一步:创建实体类ViewBean
--------------------------------------------------------------------------------------------------------/** * Created by Jabez on 2017/3/24. */ public class ViewBean { private int color;//圆环颜色 private String text;//版块文字 private float data;//数据 private float angle;//扫过弧度 public float getAngle() { return angle; } public void setAngle(float angle) { this.angle = angle; } public int getColor() { return color; } public void setColor(int color) { this.color = color; } public String getText() { return text; } public void setText(String text) { this.text = text; } public float getData() { return data; } public void setData(float data) { this.data = data; } }上述代码注释很清楚,不过多解释啦!
-----------------------------------------
第二步:新建一个自定义动画类CustomAnimation通过上述自定义动画,实际上就是更改圆弧的弧度,更改一次就重新绘制一次,特别要提的就是上面的一个percent(百分占比)算法,import java.util.List; /** * Created by Jabez on 2017/3/24. */ public class CustomAnimation extends Animation { private View view; private List<ViewBean> viewBeanList; private float total;//总金额,需要传递过来 public CustomAnimation(View view,List<ViewBean> viewBeenList, float total){ this.view = view; this.viewBeanList = viewBeenList; this.total = total; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if(interpolatedTime <= 1.0f) { for (int i = 0; i < viewBeanList.size(); i++) { ViewBean viewBean = viewBeanList.get(i); float percent = (viewBean.getData() / total) * 360 * interpolatedTime; viewBean.setAngle(percent); //重新绘制 view.postInvalidate(); } } } }
viewBean.getData() / total是获取这条数据在全部数据中所占比例,然后 viewBean.getData() / total * 360就是在整个圆中的占比,
最后 (viewBean.getData() / total) * 360 * interpolatedTime,interpolatedTime是插入值时间(范围是0~1.0),所以算法算出来就是当前时间上,圆弧的角度。
举个简单的例子就是你设置了2000毫秒的动画时间,当执行到1s时,interpolatedTime = 0.5,算出来就是圆弧角度了。
第三步:新建一个CustomArcView类
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import com.cdbhe.myproject.custom.CustomAnimation; import java.util.ArrayList; import java.util.List; /** * Created by Jabez on 2017/3/24. */ public class CustomArcView extends View { private Paint paint; private Paint textPaint; private List<ViewBean> viewBeenList = null; private float total = 0; private CustomAnimation customAnimation; private int delayMillis = 2000; public CustomArcView(Context context) { super(context); } public CustomArcView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public void init(){ ViewBean viewBean = new ViewBean(); viewBean.setColor(Color.CYAN); viewBean.setText("余额"); viewBean.setData(100); viewBeenList = new ArrayList<>(); viewBeenList.add(viewBean); //初始化画笔 paint = new Paint(); paint.setAntiAlias(true);//设置抗锯齿 paint.setStyle(Paint.Style.FILL);//设置为线条样式 //初始化文字画笔 textPaint = new Paint(); textPaint.setColor(Color.BLACK); textPaint.setStyle(Paint.Style.STROKE); textPaint.setTextSize(sp2px(14)); for(int i=0;i<viewBeenList.size();i++){ total+=viewBeenList.get(i).getData(); } initAnim(); } public void initAnim(){ customAnimation = new CustomAnimation(this,viewBeenList,total); customAnimation.setDuration(delayMillis); customAnimation.setFillAfter(true); customAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); startAnimation(customAnimation); } public void setViewBeanList(List<ViewBean> viewBeanList){ this.viewBeenList = viewBeanList; initAnim(); } public void setDelayMillis(int delayMillis){ this.delayMillis = delayMillis; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); RectF rectF = new RectF(10, 10, 300, 300);//设置绘制外切矩阵 float start = 0;//绘制开始的弧度 float cy = 20;//y轴坐标 for (int i = 0; i < viewBeenList.size(); i++) {//循环绘制 ViewBean viewBean = viewBeenList.get(i); //绘制圆弧 paint.setColor(viewBean.getColor());//设置画笔颜色 canvas.drawArc(rectF, start, viewBean.getAngle(), true, paint);//绘制圆弧 start += viewBean.getAngle(); //绘制标注 canvas.drawCircle(320,cy,10,paint); //绘制文字 canvas.drawText(viewBean.getText() + " " + viewBean.getData(),340,cy+5,textPaint); cy += 35; } //画中心白色圆 paint.setColor(Color.WHITE); canvas.drawCircle(155, 155, 50, paint); } /** * dp 2 px * * @param dpVal */ protected int dp2px(int dpVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics()); } /** * sp 2 px * * @param spVal * @return */ protected int sp2px(int spVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, getResources().getDisplayMetrics()); } }上面的代码已经很清晰了,一看就懂的,具体步骤为:先定义需要的变量,如全局画笔Paint(需要全局,因为如果定义在onDraw的话,重新绘制又会new,会增大系统开销),
还有就是绘制文字的textPaint,还有就是上面写出来的。
在构造里面就调用初始化方法,初始化初始List(在不传数值的情况下默认一条数据),初始化画笔以及动画
PS:customAnimation.setInterpolator(new AccelerateDecelerateInterpolator());这个是设置加载的播放速度的,有如下实例:AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速。
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速。
CycleInterpolator 动画循环方法特定的次数,速率改变沿着正弦曲线。
DecelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始减速。
LinearInterpolator 匀速速率
接着就是onDraw方法了,canvas的方法就不多讲了,百度都都搜到,讲的话就废话了
-------------------------------------------------------------------------------
最后一步,调用吧:
import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import com.cdbhe.myproject.R; import com.cdbhe.myproject.layout.CustomArcView; import com.cdbhe.myproject.layout.ViewBean; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private Button btn; private CustomArcView customArcView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button)findViewById(R.id.send); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { initComp(); } }); } private void initComp(){ int[] colors = new int[]{Color.BLACK,Color.CYAN,Color.GRAY,Color.GREEN}; String[] texts = new String[]{"余额","余额宝","亏欠","收入"}; float[] datas = new float[]{20,40,10.00f,30.00f}; customArcView = (CustomArcView)findViewById(R.id.customView); List<ViewBean> viewBeanList = new ArrayList<>(); for(int i=0;i<colors.length;i++){ ViewBean viewBean = new ViewBean(); viewBean.setColor(colors[i]); viewBean.setText(texts[i]); viewBean.setData(datas[i]); viewBeanList.add(viewBean); } customArcView.setDelayMillis(1000); customArcView.setViewBeanList(viewBeanList); } }点击按钮后就如效果图所示,结篇!