价格趋势图你们懂的 废话不多说直接看图

图片

         

 

package com.example.pricetrend;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

public class PriceTrendView extends View {

    private Bitmap bitmapLine;// 线
    private Bitmap bitmapDot;//
    private Bitmap bitmapTitle;// title
    private Bitmap bitmapPoint;// point
    private int dotWidth;// 点的宽
    private int dotHeigth;// 点的高
    private int mWidth;// 屏幕的宽
    private int mHeigth;// 屏幕的高
    private int nNit = 116;// 最小刻度
    private int nNitNum = 3;// 刻度数
    private int RectHeigth;// 整个矩阵的高
    private int RectWidth;// 整个矩阵的宽
    private float vpScale;// 矩阵高:刻度数 代表每一刻度要的屏幕高
    private Paint paintLine;// 画矩阵的线画笔
    private Paint paintArea;// 画矩阵面积画笔
    private Paint paintAreaSide; // 画值面积区域画笔
    private Path pathArea; // 画值面积区域path
    private Path pathAreaSide; // 画值面积区域边框path
    private int Space;// 矩阵与屏幕的间隔
    private int Start;// 起点
    private int LineCurrent = 2;//当前线在第几个刻度
    private int Prices[] = { 250, 130, 240, 220, 230, 0, 100, 20, 24, 300,    40, 20, 120, 130, 110, 150 ,30,20,15,180,170,150,110,120,50,30,80,71,65,90,50,60};
    private Context context;
    private int seekOffset = 0;// 根据seekbar 滑动View
    private OnPriceChangeListener onPriceChangeListener;// 当前点对应的价格的变化监听
    boolean  flag=false;//判断是否画上面title 部分
    public PriceTrendView(Context context, AttributeSet attrs,

    int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
        this.context = context;
        init();
    }

    public PriceTrendView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        this.context = context;
        init();
    }

    public PriceTrendView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        this.context = context;
        init();
    }

    private void init() {
        // TODO Auto-generated method stub
        Space = dip2px(context, 20);
        Start = dip2px(context, 16);
        // BitmapFactory.decodeResource(context.getResources(),
        // R.drawable.icon);
        // 获取到线和点的图片转为bitmap对象
        Drawable d_line = getResources().getDrawable

        (R.drawable.trend_line);
        Drawable d_dot = getResources().getDrawable

        (R.drawable.trend_dot);
        BitmapDrawable bd_line = (BitmapDrawable) d_line;
        BitmapDrawable bd_dot = (BitmapDrawable) d_dot;
        bitmapLine = bd_line.getBitmap();
        bitmapDot = bd_dot.getBitmap();
        bitmapTitle=BitmapFactory.decodeResource(context.getResources(), R.drawable.trend_loudou_bar);
        bitmapPoint=BitmapFactory.decodeResource(context.getResources(), R.drawable.trend_loudou);
        // 得到点图片的高和宽
        dotWidth = bitmapDot.getWidth();
        dotHeigth = bitmapDot.getHeight();

        // 得到屏幕的高和宽
        WindowManager wm = (WindowManager) getContext

        ().getSystemService(Context.WINDOW_SERVICE);
        mWidth = wm.getDefaultDisplay().getWidth();// 屏幕宽度
        RectWidth = mWidth - Start * 2;// view的宽度
        mHeigth = wm.getDefaultDisplay().getHeight();// 屏幕宽度
        // 屏幕的3/1 为pricetrendview 的高度 即RectHeigth
        RectHeigth = mHeigth*4 /9;
        /*
         * Start=mHeigth/6; vpScale=(RectHeigth/(nNit*nNitNum));
         */

        // 画线的画笔
        paintLine = new Paint();
        paintLine.setColor(Color.BLACK);
        paintLine.setStrokeWidth(1);
        paintLine.setAntiAlias(true);
        paintLine.setStyle(Paint.Style.STROKE);

        // 画值得区域的画笔
        paintArea = new Paint();
        paintArea.setColor(Color.parseColor("#c6f0ff"));
        paintArea.setStrokeWidth(1);
        paintArea.setAntiAlias(true);
        paintArea.setStyle(Paint.Style.FILL);

        // 画值得区域边框的画笔
        paintAreaSide = new Paint();
        paintAreaSide.setColor(Color.parseColor("#81ddff"));
        paintAreaSide.setStrokeWidth(1);
        paintAreaSide.setAntiAlias(true);
        paintAreaSide.setStyle(Paint.Style.STROKE);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        // canvas.drawRect(Space, 0, mWidth-Space, RectHeigth, paintLine);

        // 画值区域
        pathArea = new Path();
        for (int i = 0; i < Prices.length; i++) {
            if (i == 0) {
                pathArea.moveTo(Space * i - seekOffset,    (nNit * nNitNum - Prices[i]*3/4) * RectHeigth / (nNit * nNitNum));
            } else {
                pathArea.lineTo(Space * i - seekOffset,(nNit * nNitNum - Prices[i]*3/4) * RectHeigth / (nNit * nNitNum));
            }
        }
        pathArea.lineTo(Space * (Prices.length - 1) - seekOffset,RectHeigth);
        pathArea.lineTo(-seekOffset, RectHeigth);
        pathArea.close();
        canvas.drawPath(pathArea, paintArea);
        // 画值区域边框

        pathAreaSide = new Path();
        for (int i = 0; i < Prices.length; i++) {
            if (i == 0) {
                pathAreaSide.moveTo(Space * i -    seekOffset, (nNit * nNitNum - Prices[i]*3/4) * RectHeigth/ (nNit * nNitNum));
            } else {
                pathAreaSide.lineTo(Space * i - seekOffset, (nNit * nNitNum - Prices[i]*3/4) * RectHeigth/ (nNit * nNitNum));
            }
        }
        pathAreaSide.lineTo(Space * (Prices.length - 1) -    seekOffset, RectHeigth);
        pathAreaSide.lineTo(-seekOffset, RectHeigth);
        pathAreaSide.close();
        canvas.drawPath(pathAreaSide, paintAreaSide);

        // 画矩形区域
        canvas.drawLine(0, RectHeigth*1/4, 0, RectHeigth, paintLine);
        canvas.drawLine(0, RectHeigth-1, RectWidth,    RectHeigth-1, paintLine);
        canvas.drawLine(RectWidth-1, RectHeigth-1, RectWidth-1, RectHeigth*1/4,paintLine);
        canvas.drawLine(0, RectHeigth*1/4, RectWidth, RectHeigth*1/4, paintLine);

        // 画矩形中的两条线
        canvas.drawLine(0, RectHeigth*2 / 4, RectWidth,    RectHeigth*2 / 4, paintLine);
        canvas.drawLine(0, RectHeigth *3 / 4, RectWidth,    RectHeigth*3/ 4, paintLine);

        if(flag){
        // 画线图片
        RectF rectf = new RectF(Space * LineCurrent - seekOffset- dip2px(context, 1),    0, Space * LineCurrent + dip2px(context, 1) - seekOffset, RectHeigth);
        canvas.drawBitmap(bitmapLine, null, rectf,    paintLine);                    
        //画title 图片
        RectF rectfTitle = new RectF(0,    0, RectWidth, dip2px(context, 7));
        canvas.drawBitmap(bitmapTitle, null, rectfTitle,    paintLine);
        //画节点 图片
        canvas.drawBitmap(bitmapPoint, Space * LineCurrent -dotWidth / 2 - seekOffset- dip2px(context, 1), dip2px(context, 3),    paintLine);
        }else{
        // 画线图片
        RectF rectf = new RectF(Space * LineCurrent - seekOffset- dip2px(context, 1),    RectHeigth/4, Space * LineCurrent + dip2px(context, 1) - seekOffset, RectHeigth);
        canvas.drawBitmap(bitmapLine, null, rectf,    paintLine);            
        }
        // 画点图片
        canvas.drawBitmap(bitmapDot, Space * LineCurrent -dotWidth / 2 - seekOffset, (nNit * nNitNum - Prices[LineCurrent]*3/4)* RectHeigth / (nNit * nNitNum) - dotHeigth / 2, paintLine);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int

    heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);
        setMeasuredDimension(RectWidth, RectHeigth+dotHeigth);// 设置控件大小
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            x = event.getX();
            flag=true;
            OverrideDraw(x);
            break;
        case MotionEvent.ACTION_MOVE:
            x = event.getX();
            flag=true;
            OverrideDraw(x);
            break;
        case MotionEvent.ACTION_UP:
            flag=false;
            invalidate();
            break;
        default:
            break;
        }
        return true;

    }

    /**
     * 
     * 得到点击后的位置点的位置
     * 
     */
    public void OverrideDraw(float x) {
        LineCurrent = (int) (x / Space + 1+seekOffset/Space);
        if (LineCurrent <= 0) {
            LineCurrent = 0;
        } else if (LineCurrent >= Prices.length - 1) {
            LineCurrent = Prices.length - 1;
        }
        invalidate();
        // 调用对点对应价格变化监听的接口
        onPriceChangeListener.onChange(Prices

        [LineCurrent] + "");
    }

    /**
     * 
     * 滑动view 换算没做
     */
    public void SetSeekOffset(int offset) {
        seekOffset = offset;
        invalidate();
    }

    /**
     * 
     * 对点对应价格变化监听
     */
    public void setOnPriceChangeListener(OnPriceChangeListener

    onPriceChangeListener) {
        this.onPriceChangeListener = onPriceChangeListener;
    }

    /**
     * 得到点对应价格
     * */
    public int getPrice() {
        return Prices[LineCurrent];
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources

        ().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    public static interface OnPriceChangeListener {
        void onChange(String price);
    }

}

 

posted on 2014-07-15 09:09  青年程序猿  阅读(444)  评论(0)    收藏  举报