自定义圆头柱状图
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 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; }
相关文章推荐
- c# 拆分合并字符串 Split Join
- LeetCode 17. Letter Combinations of a Phone Number高效解法
- ioctl用法详解
- Qt学习之路(59): 编写跨平台的程序
- 实现TOOLBAR中颜色对话框的添加
- (第13讲)哈希表的开放地址法中的线性探测
- Same-origin security policy
- 【iOS】网络操作与AFNetworking
- nginx如何设置自定义404页面
- UVa 10106 Product
- 自我介绍和决心书
- C# 委托、事件
- oracle日期函数2!
- 将博客搬至CSDN
- the service threw an unknown exception in SCOM 2012
- CocoaPods安装
- 部署FIM 2010 R2—1先决条件准备
- 部署FIM 2010 R2—2服务账号和其他准备
- 部署FIM 2010 R2—3安装FIM 2010 R2 Service and Portal
- 部署FIM 2010 R2—4安装FIM 2010 R2 Synchronization Service