项目中用到下面的效果:
总共有四种状态,分四种颜色,根据传入的每种状态的比例值在直线上显示各自的长度。
这种效果最终用两种方法完成。
第一种方法是首先想到的一种方法,自定义一个FrameLayout,在里面有四个互相重叠的Imageview或者textview。背景使用shpe绘制四个圆角矩形。然后根据传入的值动态改变imageview或者textview的宽度
shape:
<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
* 邮箱:[email protected]
*/
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;jint) (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
* 邮箱:[email protected]
*/
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+1];
}
mRect2.right = (int) (mWidth*scale2);
float scale3 = 0;
for (int j = 0; j < scales.length - 2; j++) {
scale3 += scales[j+2];
}
mRect3.right = (int) (mWidth*scale3);
float scale4 = 0;
for (int j = 0; j < scales.length - 3; j++) {
scale4 += scales[j+3];
}
mRect4.right = (int) (mWidth*scale4);
invalidate();
}
}
绘制流程:
先绘制灰色、红色,黄色、蓝色。一层一层的覆盖。
最主要的方法就是setScales() 方法。因为绘制的流程是先绘制最后一个颜色(灰色)其实灰色永远都是绘制百分之百的宽度。红色的宽度就是总宽度乘以(1-灰色比例),黄色宽度是 总宽度乘以(1-灰色比例-红色宽度),蓝色宽度是总宽度乘以它自己的比例或者乘以(1-灰色比例-红色比例-黄色比例)。
OK完事。源码在图表库中的ScaleView。