1. 程式人生 > >Android 支付寶收益(折線)圖、淘寶收益圖

Android 支付寶收益(折線)圖、淘寶收益圖

話不多說,先上圖
這裡寫圖片描述
最近看了一個博文,個人覺得不錯,大家能在開發中獲取會用到這樣的東西,所以我把這位大神的文章給貼上過來,希望這個大哥看見之後,不要見怪哈!這是他的部落格地址

http://blog.csdn.net/xiangzhihong8/article/details/50990788
我們知道要實現在canvas上畫線,不就是要搞一個paint嘛,然後首先肯定要設定下paint的屬性,那麼畫文字呢,不就是Textpaint嗎,對,就是這麼簡單,接下來怎麼畫,折線圖主要分為X軸和y軸,x軸表示日期,y表示收益,好,說道這裡,大家應該知道怎麼去做了,下面直接貼程式碼,
接下來是程式碼的實現步驟:

這個方法是,畫x,y座標系的,以及上面的日期和收益了

private void drawCoordinate(Canvas canvas) {
    //座標系畫筆
    Paint coordinatePaint = new Paint();
    coordinatePaint.setAntiAlias(true);
    coordinatePaint.setStrokeWidth(1);
    coordinatePaint.setColor(getResources().getColor(R.color.c5));
    //座標系文字畫筆
    TextPaint coordinateTextPaint = new TextPaint();
coordinateTextPaint.setAntiAlias(true); coordinateTextPaint.setTextSize(scaleTextSize); coordinateTextPaint.setAntiAlias(true); coordinateTextPaint.setColor(scaleTextColor); coordinateTextPaint.setTextAlign(Align.CENTER); //水平的刻度線 float verticalScaleStep = getVerticalScaleStep();
coordinateTextPaint.setTextAlign(Align.RIGHT); float textHeight = getTextHeight(coordinateTextPaint, "8"); for (int i = 0; i < maxVerticalScaleValue; i++) { float y = getHeight() - bottomPadding - (verticalScaleStep * i); canvas.drawLine(leftPadding, y, getWidth() - rightPadding, y, coordinatePaint); canvas.drawText(i + "", leftPadding - 13, y + textHeight / 2, coordinateTextPaint); } //垂直的刻度線 float horizontalScaleStep = getHorizontalScaleStep(); for (int i = 0; i < line.getSize(); i++) { float x = leftPadding + (horizontalScaleStep * i); if (i == 0) { canvas.drawLine(x, topPadding, x, getHeight() - bottomPadding, coordinatePaint); } coordinateTextPaint.setColor(mTouchIndex == i ? verticalLineColor : scaleTextColor); coordinateTextPaint.setTextAlign(i == 0 ? Align.LEFT : Align.CENTER); canvas.drawText(line.getPoint(i).getX(), x, getHeight() - bottomPadding + textHeight + 10, coordinateTextPaint); } }

但是產品有個需求啊,就是點選當前日期可以檢視我的收益,並且在交匯點上展示出來

private void drawCurve(Canvas canvas) {
    Paint curvePaint = new Paint();//曲線畫筆
    curvePaint.setColor(curveColor);
    curvePaint.setAntiAlias(true);
    curvePaint.setStrokeWidth(curveStrokeWidth);

    float horizontalScaleStep = getHorizontalScaleStep();
    float lastXPixels = 0, newYPixels = 0;
    float lastYPixels = 0, newXPixels = 0;
    float useHeight = getHeight() - bottomPadding - topPadding;
    for (int i = 0; i < line.getSize(); i++) {
        float yPercent = line.getPoint(i).getY() / maxVerticalScaleValue;
        if (i == 0) {
            lastXPixels = leftPadding + i * horizontalScaleStep;
            lastYPixels = getHeight() - bottomPadding - useHeight * yPercent;
        } else {
            newXPixels = leftPadding + i * horizontalScaleStep;
            newYPixels = getHeight() - bottomPadding - useHeight * yPercent;
            canvas.drawLine(lastXPixels, lastYPixels, newXPixels, newYPixels, curvePaint);
            lastXPixels = newXPixels;
            lastYPixels = newYPixels;
        }
        line.getPoint(i).fLineX = lastXPixels;
        line.getPoint(i).fLineY = lastYPixels;
    }
}

點選交匯點,有文字提示說明,

private void drawTipRect(Canvas canvas) {
    if (mTouchIndex == -1) return;
    LinePoint point = line.getPoint(mTouchIndex);
    float x = point.fLineX;
    float y = point.fLineY;

    // 描繪豎線
    Paint paint = new TextPaint();
    PathEffect effects = new DashPathEffect(new float[]{5, 5, 5, 5}, 1);
    paint.setPathEffect(effects);
    paint.setAntiAlias(true);
    paint.setStrokeWidth(verticalLineStrokeWidth);
    paint.setColor(verticalLineColor);
    canvas.drawLine(x, topPadding, x, getHeight() - bottomPadding, paint);

    //描繪交匯圓點
    paint.setPathEffect(null);
    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    paint.setColor(Color.WHITE);
    canvas.drawCircle(x, y, circleRadius, paint);
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(circleColor);
    paint.setStrokeWidth(circleStrokeWidth);
    canvas.drawCircle(x, y, circleRadius, paint);

    float midY = (topPadding + getHeight() - bottomPadding) / 2;
    float midX = (leftPadding + getWidth() - rightPadding) / 2;

    //描繪圓角矩形
    TextPaint textPaint = new TextPaint();
    textPaint.setTextSize(tipTextSize);
    textPaint.setTextAlign(Align.CENTER);
    textPaint.setColor(tipTextColor);
    textPaint.setAntiAlias(true);

    String label = tipPrefix + point.getY();
    float textWidth = textPaint.measureText(label) + 15;
    float textHeight = getTextHeight(textPaint, label) + 8;
    float hMargin = 10;//水平間距
    float vMargin = 8;//垂直間距
    float w = textWidth + hMargin * 2;//寬
    float h = textHeight + vMargin * 2;//高

    RectF rect = new RectF();
    if (x > midX) {
        rect.right = x - hMargin;
        rect.left = x - w;
    } else {
        rect.left = x + hMargin;
        rect.right = x + w;
    }

    if (y > midY) {
        rect.top = y - h;
        rect.bottom = y - vMargin;
    } else {
        rect.bottom = y + h;
        rect.top = y + vMargin;
    }
    Paint roundRectPaint = new Paint();
    roundRectPaint.setColor(tipRectColor);
    roundRectPaint.setStyle(Paint.Style.FILL);
    roundRectPaint.setAntiAlias(true);
    canvas.drawRoundRect(rect, 3, 3, roundRectPaint);

    // 描繪圓角矩形中間的文字
    float roundTextX = (rect.left + rect.right) / 2;
    float roundTextY = (rect.top + rect.bottom + getTextHeight(textPaint, label)) / 2;
    canvas.drawText(label, roundTextX, roundTextY, textPaint);
}

好了核心的程式碼就這麼多了,由於我們把它當做的是控制元件再用,那麼我們在初始化的時候,肯定會引入一些自定義的樣式表,

private void initViews(AttributeSet attrs, int defStyle) {
    TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.LineGraph, defStyle, 0);
    scaleTextSize = typedArray.getDimension(R.styleable.LineGraph_scale_text_size, 20);
    scaleTextColor = typedArray.getColor(R.styleable.LineGraph_scale_text_color, getResources().getColor(R.color.c5));
    tipRectColor = typedArray.getColor(R.styleable.LineGraph_tip_rect_color, getResources().getColor(R.color.c8));
    tipTextSize = typedArray.getDimension(R.styleable.LineGraph_tip_text_size, 22);
    tipTextColor = typedArray.getColor(R.styleable.LineGraph_tip_text_color, getResources().getColor(R.color.c12));
    curveStrokeWidth = typedArray.getDimension(R.styleable.LineGraph_curve_stroke_width, 4);
    curveColor = typedArray.getColor(R.styleable.LineGraph_curve_color, getResources().getColor(R.color.c8));
    verticalLineStrokeWidth = typedArray.getDimension(R.styleable.LineGraph_vertical_line_stroke_width, 2);
    verticalLineColor = typedArray.getColor(R.styleable.LineGraph_vertical_line_color, getResources().getColor(R.color.c8));
    circleStrokeWidth = typedArray.getDimensionPixelSize(R.styleable.LineGraph_circle_stroke_width, 3);
    circleColor = typedArray.getColor(R.styleable.LineGraph_circle_color, getResources().getColor(R.color.c8));
    circleRadius = typedArray.getDimensionPixelSize(R.styleable.LineGraph_circle_radius, 7);
    typedArray.recycle();

    bottomPadding = dip2px(getContext(), 20);
    topPadding = dip2px(getContext(), 10);
    leftPadding = dip2px(getContext(), 20);
    rightPadding = dip2px(getContext(), 10);
}

樣式表文件我就不多說了,行如下面的格式

<declare-styleable name="LineGraph">
    <attr name="scale_text_size" format="dimension" />
    <attr name="scale_text_color" format="color" />
    <attr name="tip_text_size" format="dimension" />
    <attr name="tip_text_color" format="color" />
    <attr name="tip_rect_color" format="color" />
    <attr name="curve_stroke_width" format="dimension" />
    <attr name="curve_color" format="color" />
    <attr name="vertical_line_stroke_width" format="dimension" />
    <attr name="vertical_line_color" format="color" />
    <attr name="circle_stroke_width" format="dimension" />
    <attr name="circle_color" format="color" />
    <attr name="circle_radius" format="dimension" />
</declare-styleable>