[原]Android自定义View直线比例图

项目中用到下面的效果: 总共有四种状态,分四种颜色,根据传入的每种状态的比例值在直线上显示各自的长度。 这

项目中用到下面的效果:

[原]Android自定义View直线比例图

总共有四种状态,分四种颜色,根据传入的每种状态的比例值在直线上显示各自的长度。

这种效果最终用两种方法完成。

第一种

第一种方法是首先想到的一种方法,自定义一个FrameLayout,在里面有四个互相重叠的Imageview或者textview。背景使用shpe绘制四个圆角矩形。然后根据传入的值动态改变imageview或者textview的宽度

shape:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 圆角 --> <corners android:radius="10dp" /> <solid android:color="@color/patrol_no_start_gray"/></shape>

view:

package com.chs.listtext;import android.content.Context;import android.util.AttributeSet;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.TextView;/** * 作者:chs on 2016/9/27 14:02 * 邮箱:657083984@qq.com */public class ProgressScaleView extends FrameLayout { private int[] resId = new int[]{R.drawable.shape_patrol_corners_gray, R.drawable.shape_patrol_corners_red, R.drawable.shape_patrol_corners_yellow, R.drawable.shape_patrol_corners_blue}; private double [] scales = new double[4]; private int mWidth; public ProgressScaleView(Context context) { super(context); init(context); } public ProgressScaleView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public ProgressScaleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } public void setScales(double[] scales) { this.scales = scales; invalidate(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); int count = getChildCount(); //依次改变textview的宽度 for (int i = 0; i < count; i++) { TextView view = (TextView) getChildAt(i); float scale = 0; for(int j = 0;j<scales.length-i;j++){ scale+=scales[j]; } view.getLayoutParams().width = (int) (mWidth*scale); } } private void init(Context context) { mWidth = context.getResources().getDisplayMetrics().widthPixels-DensityUtil.dip2px(context, 40); //创建四个textview 宽度都为ViewGroup.LayoutParams.MATCH_PARENT 依次覆盖 for (int i = 0; i < 4; i++) { TextView textView = new TextView(context); textView.setHeight(DensityUtil.dip2px(context, 20)); textView.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); textView.setBackgroundResource(resId[i]); addView(textView); } }}

第二种

第一种还是有点麻烦,得写四种shape 创建textview对象。其实想一想这个效果直接在view上绘制小圆角矩形不就行了,于是有了第二种:

package com.hsm.bxt.widgets;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;import com.hsm.bxt.utils.DensityUtil;/** * 作者:chs on 2016/9/28 10:03 * 邮箱:657083984@qq.com */public class ScaleView extends View { private int mWidth; private RectF mRect1; private RectF mRect2; private RectF mRect3; private RectF mRect4; private Paint mPaint; private int [] mColors = new int[]{Color.parseColor("#C4D4E8"),Color.parseColor("#FF727A"),Color.parseColor("#FFC636"),Color.parseColor("#44B2FE")}; private static final int BG_COLOR = Color.parseColor("#FFFFFF"); public ScaleView(Context context) { super(context); init(context); } public ScaleView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public ScaleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { setWillNotDraw(false); int height = DensityUtil.dip2px(context, 10); mWidth = context.getResources().getDisplayMetrics().widthPixels-DensityUtil.dip2px(context, 40); mRect1 = new RectF(0,0,0, height); mRect2 = new RectF(0,0,0, height); mRect3 = new RectF(0,0,0, height); mRect4 = new RectF(0,0,0, height); mPaint = new Paint(); mPaint.setAntiAlias(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));// super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mWidth = w; super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(BG_COLOR); mPaint.setColor(mColors[0]); canvas.drawRoundRect(mRect1,15,15,mPaint); mPaint.setColor(mColors[1]); canvas.drawRoundRect(mRect2,15,15,mPaint); mPaint.setColor(mColors[2]); canvas.drawRoundRect(mRect3,15,15,mPaint); mPaint.setColor(mColors[3]); canvas.drawRoundRect(mRect4,15,15,mPaint); } /** * 给数据赋值 * @param scales */ public void setScales(double[] scales){ float scale1 = 0; for (int j = 0; j < scales.length - 0; j++) { scale1 += scales[j]; } mRect1.right = (int) (mWidth*scale1); float scale2 = 0; for (int j = 0; j < scales.length - 1; j++) { scale2 += scales[j]; } mRect2.right = (int) (mWidth*scale2); float scale3 = 0; for (int j = 0; j < scales.length - 2; j++) { scale3 += scales[j]; } mRect3.right = (int) (mWidth*scale3); float scale4 = 0; for (int j = 0; j < scales.length - 3; j++) { scale4 += scales[j]; } mRect4.right = (int) (mWidth*scale4); invalidate(); }}

绘制流程:

先绘制灰色、红色,黄色、蓝色。一层一层的覆盖。

最主要的方法就是setScales() 方法。因为绘制的流程是先绘制最后一个颜色(灰色)其实灰色永远都是绘制百分之百的宽度。红色的宽度就是总宽度乘以(1-灰色比例),黄色宽度是 总宽度乘以(1-灰色比例-红色宽度),蓝色宽度是总宽度乘以它自己的比例或者乘以(1-灰色比例-红色比例-黄色比例)。

OK完事。源码在 图表库 中的ScaleView。

未登录用户
全部评论0
到底啦