public class RatioBar extends View {
private float mMaxRatio = 0.8f;
private float mMinRatio = 0.2f;
private final RectF mRectF = new RectF();
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mSplitWidth = 10;
private int mRiseColor, mFallColor;
private int mRise, mFall;
public RatioBar(@NonNull Context context) {
this(context, null);
}
public RatioBar(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RatioBar(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
mRiseColor = getColor(xxx);
mFallColor = getColor(xxx);
}
@SuppressLint("EMDrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
RectF rectF = mRectF;
Paint paint = mPaint;
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int startX = paddingLeft;
int startY = paddingTop;
int width = getWidth() - paddingLeft - paddingRight;
int height = getHeight() - paddingTop - paddingBottom;
// 约定最小宽高比3:1
if (width < height * 3) {
startY = (height - width / 3) / 2 + paddingTop;
height = width / 3;
}
int radius = height / 2;
int ratioStart = radius;
int ratioEnd = width - radius;
int splitWidth = mSplitWidth;
int ratioWidth;
int rise = mRise;
int fall = mFall;
int total = rise + fall;
if (rise == 0 || fall == 0) {
Path path = new Path();
path.moveTo(startX + ratioStart, startY);
path.lineTo(startX + ratioEnd, startY);
rectF.set(startX + ratioEnd - radius, startY, startX + ratioEnd + radius, startY + height);
path.arcTo(rectF, -90, 180, false);
path.lineTo(startX + ratioStart, startY + height);
rectF.set(startX, startY, startX + height, startY + height);
path.arcTo(rectF, 90, 180, false);
path.close();
paint.setStyle(Paint.Style.FILL);
if (fall == 0) {
paint.setColor(mRiseColor);
} else {
paint.setColor(mFallColor);
}
canvas.drawPath(path, paint);
} else {
int triangleWidth = radius;// 中间斜着的三角的宽度
ratioWidth = ratioEnd - ratioStart - splitWidth - triangleWidth;//比例条的宽度
float fixRiseRatio = Math.max(mMinRatio, Math.min(mMaxRatio, rise / (float) total));
int riseWidth = (int) (ratioWidth * fixRiseRatio);
int fallWidth = ratioWidth - riseWidth;
Path path = new Path();
path.moveTo(startX + ratioStart, startY);
path.lineTo(startX + ratioStart + riseWidth + triangleWidth, startY);
path.lineTo(startX + ratioStart + riseWidth, startY + height);
path.lineTo(startX + ratioStart, startY + height);
rectF.set(startX, startY, startX + height, startY + height);
path.arcTo(rectF, 90, 180, false);
path.close();
paint.setStyle(Paint.Style.FILL);
paint.setColor(mRiseColor);
canvas.drawPath(path, paint);
path = new Path();
path.moveTo(startX + ratioEnd, startY + height);
path.lineTo(startX + ratioEnd - fallWidth - triangleWidth, startY + height);
path.lineTo(startX + ratioEnd - fallWidth, startY);
path.lineTo(startX + ratioEnd, startY);
rectF.set(startX + ratioEnd - radius, startY, startX + ratioEnd + radius, startY + height);
path.arcTo(rectF, -90, 180, false);
path.close();
paint.setStyle(Paint.Style.FILL);
paint.setColor(mFallColor);
canvas.drawPath(path, paint);
}
}
public void setSplitWidth(int splitWidth) {
mSplitWidth = splitWidth;
}
/**
* 给展示的比例设置一个最大最小的限制
* @param maxRatio
* @param minRatio
*/
public void setRatioLimit(float minRatio, float maxRatio) {
if (maxRatio <= minRatio) {
return;
}
mMaxRatio = Math.max(0, Math.min(maxRatio, 1));
mMinRatio = Math.max(0, Math.min(minRatio, 1));
}
public void setData(int rise, int fall) {
this.mRise = rise;
this.mFall = fall;
postInvalidate();
}
}
网友评论