[原]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
到底啦