自定义View之一(垂直柱状图)

第一次写博客,想想心里还有点小激动呢...

代码注释很少,但实现很简单,大家看看就明白了

自己项目里抠出来的代码,希望能起到抛砖引玉的效果,如果有更好的实现,请不吝赐教

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

首先在attrs.xml中声明自定义view的属性:

    <declare-styleable name="ChartBaseView">
        <attr name="icon" format="reference" />
        <attr name="background" format="reference|color" />
    </declare-styleable>

定义自定义图表基类(因为我定义的不止这一种图表,所以才定义了一个基类):

public class ChartBaseView extends View {

    private static final String TAG = "ChartBaseView";
    protected Bitmap mIcon;
    private Paint mPaint;
    private int mBackgroundColor;
    protected int mViewHeight;
    protected int mViewWidth;
    protected static final float PERCENT_TO_DRAW_TEXT = 0.45f;//view中画文本的区域大小占的百分比
    protected String mDataValue;//数据值
    protected String mDataUnit;//数据的单位
    protected String mDataType;//是哪种类型的图表
    private static final int TEXT_SIZE_VALUE = 22;
    private static final int TEXT_SIZE_UNIT = 18;
    private static final int TEXT_SIZE_TYPE = 14;
    private static final int TEXT_SPACE_VERTICAL = 5;
    private Rect mTextRect;

    public void setDataProperty(String value, String unit, String type){
        if(value == null || unit == null || type == null){
            Log.e(TAG, "propery null");
            return;
        }
        mDataValue = value;
        mDataUnit = unit;
        mDataType = type;
    }

    public void setDataValue(String value){
        mDataValue = value;
    }

    public void setDataUnit(String unit){
        mDataUnit = unit;
    }

    public void setDataType(String type){
        mDataType = type;
    }

    public ChartBaseView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

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

    protected void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ChartBaseView);
        int drawableId = typedArray.getResourceId(R.styleable.ChartBaseView_icon, R.drawable.ic_launcher);
        Log.e(TAG, "drawableId=" + drawableId + ", defaultId=" + R.drawable.ic_launcher);
        mIcon = BitmapFactory.decodeResource(getResources(), drawableId);
        mBackgroundColor = typedArray.getColor(R.styleable.ChartBaseView_background, android.R.color.white);
        typedArray.recycle();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextRect = new Rect();
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(mBackgroundColor);
        canvas.drawBitmap(mIcon, 20, 20, mPaint);
        mViewHeight = getMeasuredHeight();
        mViewWidth = getMeasuredWidth();
        //画文本
        float textWidth = 0;
        float textHeight = 0;
        mPaint.setTextSize(TEXT_SIZE_TYPE);
        float textBase = mViewHeight * PERCENT_TO_DRAW_TEXT - TEXT_SPACE_VERTICAL;
        if(mDataType != null){
            mPaint.getTextBounds(mDataType, 0, mDataType.length(), mTextRect);
            textWidth = mTextRect.width();
            textHeight = mTextRect.height();
            canvas.drawText(mDataType, mViewWidth - textWidth, textBase , mPaint);
            textBase -= TEXT_SPACE_VERTICAL + textHeight;
        }
        if(mDataUnit != null){
            mPaint.setTextSize(TEXT_SIZE_UNIT);
            textWidth = mPaint.measureText(mDataUnit);
            canvas.drawText(mDataUnit, mViewWidth - textWidth, textBase , mPaint);
        }
        if(mDataValue != null){
            mPaint.setTextSize(TEXT_SIZE_VALUE);
            canvas.drawText(mDataValue, mViewWidth - textWidth - mPaint.measureText(mDataValue), textBase, mPaint);
        }
    }
}

垂直柱状图实现:

public class SimpleVerticalBarChart extends ChartBaseView {

    public SimpleVerticalBarChart(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

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

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

    private ArrayList<Integer> mLevels;
    private ArrayList<Integer> mLevelColors;
    private static final int LEVEL_COUNT = 4;
    private Paint mLinePaint;
    private Paint mRectPaint;
    private int mColumnCount = 18;

    @Override
    protected void init(Context context, AttributeSet attrs) {
        super.init(context, attrs);
        mLinePaint = new Paint();
        mLinePaint.setColor(getResources().getColor(R.color.horizontal_bar_chart_dot_line_color));

        mRectPaint = new Paint();
        mRectPaint.setColor(getResources().getColor(R.color.horizontal_bar_chart_top_color));
    }
    //几行,几列,颜色
    public void setLevelData(ArrayList<Integer> levels){
        mLevels = levels;
        mColumnCount = levels.size();
        invalidate();
    }

    public void setLevelColors(ArrayList<Integer> levelColors){
        mLevelColors = levelColors;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float lineHeight = mViewHeight * (1 - PERCENT_TO_DRAW_TEXT)/LEVEL_COUNT;
        float columnWidth = mViewWidth*1.0f/mColumnCount;
        //画矩形
        int level;
        if(mLevels.size() > 0){
            float left = 0, top , right = columnWidth, bottom = mViewHeight;
            for(int pos = 0;pos<mColumnCount;pos++){
                level = mLevels.get(pos);
                top = bottom - level * lineHeight;
                canvas.drawRect(left, top, right, bottom, mRectPaint);
                left+= columnWidth;
                right += columnWidth;
            }
        }
        //画行
        float startY = mViewHeight * PERCENT_TO_DRAW_TEXT;
        for(int i = 0;i<LEVEL_COUNT;i++){
            canvas.drawLine(0, startY, mViewWidth, startY, mLinePaint);
            startY += lineHeight;
        }
        //画列
        float startX = 0; 
        for(int i = 0;i<mColumnCount;i++){
            canvas.drawLine(startX, mViewHeight*PERCENT_TO_DRAW_TEXT, startX, mViewHeight, mLinePaint);
            startX += columnWidth;
        }
    }
}

 

使用:

布局中使用:

<com.app.shecare.ui.view.SimpleVerticalBarChart
        android:id="@+id/shi_zhi_analyse"
         android:layout_width="match_parent"
         android:layout_height="200dp"
         shecare:background="@color/tab_text_selected"
         shecare:icon="@drawable/wechat" />

代码中设置参数(测试):

SimpleVerticalBarChart shiZhiAnalyseChart = (SimpleVerticalBarChart) view.findViewById(R.id.shi_zhi_analyse);
ArrayList<Integer> levels = new ArrayList<Integer>();
for(int i = 0;i<15;i++){
    int level = Math.abs(random.nextInt() % 4)+1;
    levels.add(level);
}
shiZhiAnalyseChart.setLevelData(levels);
shiZhiAnalyseChart.setDataProperty("89", "分", "月经分析");

 

效果截图:

posted @ 2015-08-12 22:29  RainStone  阅读(282)  评论(0)    收藏  举报