您的位置:首页 > 其它

自定义圆头柱状图

2016-07-13 16:27 330 查看
自己的项目碰到需要自定义圆头柱状图,记录下来

public abstract class BaseCoordinateView extends View {
public static final String TAG = "MChartView";

private RectF mRealRect0;
private RectF mRealRect1;
private RectF mRealRect2;

private Paint mXAxisPaint;
private Paint mYAxisPaint;

private PointF mOriginPoint;

private boolean mNeedXAxis = true, mNeedYAxis = true;

public BaseCoordinateView(Context context, AttributeSet attrs) {
super(context, attrs);

init0(attrs);
}

public BaseCoordinateView(Context context) {
super(context);

init0(null);
}

private void init0(AttributeSet attrs) {
float _1dp = ViewUtils.dp2px(getContext(), 1);

float xStroke = _1dp * 1.0f;
mXAxisPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mXAxisPaint.setStrokeWidth(xStroke);
mXAxisPaint.setColor(Color.parseColor("#9b9b9b"));
mXAxisPaint.setStyle(Paint.Style.FILL);

float yStroke = _1dp * 1.0f;
mYAxisPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mYAxisPaint.setStrokeWidth(yStroke);
mYAxisPaint.setColor(Color.LTGRAY);
mYAxisPaint.setStyle(Paint.Style.FILL);

mOriginPoint = new PointF();
}

public void reDraw() {
mRealRect0 = null;
invalidate();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if (getWidth() + getHeight() <= 0) return;

if (mRealRect0 == null) {
initRealRect();
}

if (mNeedXAxis) {
drawXAxis(canvas);
}

if (mNeedYAxis) {
drawYAxis(canvas);
}

mRealRect1.set(mRealRect0); // avoid alloc, different rectangle
mRealRect2.set(mRealRect0);
beforeDraw(canvas, mRealRect1);

drawChart(canvas, mRealRect2);
}

private void initRealRect() {
mRealRect0 = new RectF();
mRealRect0.left = getPaddingLeft();
mRealRect0.right = getWidth() - getPaddingRight();
mRealRect0.top = getPaddingTop();
mRealRect0.bottom = getHeight() - getPaddingBottom();

narrowMainRect(mRealRect0);

mOriginPoint.set(mRealRect0.left, mRealRect0.bottom);

mRealRect1 = new RectF();
mRealRect2 = new RectF();
}

protected void needXAxis(boolean isNeed) {
mNeedXAxis = isNeed;
}

protected void needYAxis(boolean isNeed) {
mNeedYAxis = isNeed;
}

/**
* Before the content draws, after draw axis.
*
* @param c
* @param realRect
*/
protected void beforeDraw(Canvas c, RectF realRect) {
}

protected abstract void drawChart(Canvas c, RectF realRect);

protected void narrowMainRect(RectF rectF) {
int padding = ViewUtils.dp2px(getContext(), 5);
ViewUtils.narrowRectF(rectF, padding);
}

public Paint getXAxisPaint() {
return mXAxisPaint;
}

public Paint getYAxisPaint() {
return mYAxisPaint;
}

private void drawXAxis(Canvas c) {
// move down to draw x axis
float offset = getXAxisOffset();
c.drawLine(mOriginPoint.x, mOriginPoint.y + offset, mRealRect0.right, mOriginPoint.y + offset, mXAxisPaint);
}

protected float getXAxisOffset() {
return mXAxisPaint.getStrokeWidth() / 2;
}

private void drawYAxis(Canvas c) {
// move left to draw y axis
float offset = getYAxisOffset();
c.drawLine(mOriginPoint.x - offset, mOriginPoint.y, mOriginPoint.x - offset, mRealRect0.top, mYAxisPaint);
}

protected float getYAxisOffset() {
return mYAxisPaint.getStrokeWidth() / 2;
}
}
public abstract class AbsPartsChartView extends BaseCoordinateView {
/**
* exactly same as list.size
* initialized in #setDatas()
*/
protected int COUNT = -1;
protected float MAX = 100;

private float mPaddingLeft = 0.0f, mPaddingRight = 0.0f;

private List<Item> mItemList;
private List<PointF> mPointList;

private boolean mPointInited = false; //

protected int mNormalColor = 0xFFf1e9e9, mHighLightColor = 0xFFffc107;

public AbsPartsChartView(Context context) {
super(context);
}

public AbsPartsChartView(Context context, AttributeSet attrs) {
super(context, attrs);
}

/**
* draw the paddings of item INSIDE the coordinate
*
* @param l left
* @param t top
* @param r right
* @param b bottom
*/
public void setInnerPadding(float l, float t, float r, float b) {
mPaddingLeft = l;
mPaddingRight = r;
}

public void setColors(int normal, int highLight) {
mNormalColor = normal;
mHighLightColor = highLight;
}

@Override
protected void drawChart(Canvas c, RectF realRect) {
if (!mPointInited) {
makePoints(realRect);
}

for (int i = 0; i < COUNT; i++) {
PointF p = mPointList.get(i);
Item item = mItemList.get(i);

drawItem(c, item, p, realRect);
}
}

private void makePoints(RectF rect) {
float width = rect.right - rect.left - mPaddingLeft - mPaddingRight;
float height = rect.bottom - rect.top;

float partWidth = width / (COUNT - 1);
float startX = rect.left + mPaddingLeft;
float startY = rect.bottom;// should bottom rect.top -> rect.bottom
for (int i = 0; i < COUNT; i++) {
Item item = mItemList.get(i);
float progress = item.progress;

float x = startX + i * partWidth;
float y;
if(progress > 0){
y = startY - progress / MAX * height;
if(y < 0){
y = rect.top;
}
}else {
y = -1;
}

PointF p = mPointList.get(i);
p.set(x, y);
}

mPointInited = true;
}

protected abstract int drawItem(Canvas c, Item item, PointF itemPoint, RectF realRect);

public void setDatas(List<Item> list) {
setDatas(list, true);
}

public void setDatas(List<Item> list, boolean needInvalidate) {
mItemList = list;

COUNT = mItemList.size();
mPointList = new ArrayList<PointF>(COUNT);
for (int i = 0; i < COUNT; i++) {
PointF p = new PointF();
mPointList.add(p);
}

mPointInited = false;

if (needInvalidate) {
invalidate();
}
}

public void setMax(float max) {
MAX = max;
}

public class Item {
public float progress;
public boolean highLight = false;
}
}

public class HistogramChartView extends AbsPartsChartView {
private float mRectWidth;
private Paint mRectPaint;

private Paint mPointPaint;

public HistogramChartView(Context context) {
super(context);

init();
}

public HistogramChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

protected void init() {
mPointPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPointPaint.setStyle(Paint.Style.FILL);
mPointPaint.setStrokeWidth(5);
mPointPaint.setColor(Color.RED);

mRectWidth = ViewUtils.dp2px(getContext(), 10);

mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRectPaint.setStyle(Paint.Style.FILL);
mRectPaint.setColor(mNormalColor);
}

@Override
protected int drawItem(Canvas c, Item item, PointF itemPoint, RectF realRect) {
if (itemPoint.y > 0) {
mRectPaint.setColor(item.highLight ? mHighLightColor : mNormalColor);
RectF rect = makeHistogramRect(itemPoint, realRect.bottom, mRectWidth);
//            c.drawRect(rect, mRectPaint);

// TODO: 2016/7/1 17:04modify ---
RoundRectShape rr = new RoundRectShape(new float[]{8, 8, 8, 8, 0, 0, 0, 0}, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(rr);
shapeDrawable.getPaint().setColor(mRectPaint.getColor());
Rect r = new Rect();
rect.round(r);
shapeDrawable.setBounds(r);
shapeDrawable.draw(c);
//---
}

return 0;
}

private RectF makeHistogramRect(PointF p, float bottom, float width) {
RectF rect = new RectF();
rect.left = p.x - width / 2;
rect.right = p.x + width / 2;
rect.top = p.y;
rect.bottom = bottom;
return rect;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: