android 自定义view实现股票K线图

来源:互联网 发布:淘宝店招牌图片 编辑:程序博客网 时间:2024/04/30 16:50

一直对类似股票曲线很感兴趣,今天有空实现了一个简单点的k线图,关键是要搞懂原点是相对那个,这个很重要,是以屏幕的原点为坐标原点还是以view的原点为坐标原点,除非是你的view没设置什么向左和向上的属性,画一张图方便理解


如果canvas相关的平移都不懂的话,建议去看看我上篇博客有讲,最好是自己动手去试试,这样才能理解的更深,

因为还要绘制刻度,所以要留点空间绘制刻度,我是直接写死了30px,没去使用paint获取文字的宽和高,嫌麻烦,还有就是给这个view设置padd值,因为绘制刻度的时候x,y最后一个刻度会被切掉一部分,我也是自己手动调试的,在实际项目中可不能这么干,直接贴代码吧,也没啥好说的,上面的理解了,看懂基本没啥问题

布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <com.klineview.KLineView        android:id="@+id/k_line_view"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="20px"        android:layout_marginLeft="10px"         /></RelativeLayout>
自定义veiw

package com.klineview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Point;import android.util.AttributeSet;import android.view.View;import java.util.List;/** * 绘制k线图 * Created by admin on 2016/12/8. */public class KLineView extends View {    private Paint paint;    private Paint textPaint;//绘制文字画笔    private int width;//view的宽度    private int height;//view的高度    private List<Point> mPoints;    private int strWidth = 30;//绘制文字所占用的宽度    public KLineView(Context context) {        this(context,null);    }    public KLineView(Context context, AttributeSet attrs) {        this(context, attrs,0);    }    public KLineView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        width = 430;        height = 530;        paint = new Paint();        textPaint = new Paint();        textPaint.setTextSize(14);        textPaint.setAntiAlias(true);        paint.setStrokeWidth(1);        paint.setColor(Color.GRAY);        paint.setStyle(Paint.Style.STROKE);        paint.setAntiAlias(true);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(width,height);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawKLine(canvas);    }    private void drawKLine(Canvas canvas) {        canvas.translate(0,height);        drawRect(canvas);        drawPoints(mPoints,canvas);    }    private void drawRect(Canvas canvas) {        canvas.drawLine(strWidth,-strWidth,strWidth,-530+2,paint);//+2是画笔的宽度        canvas.drawLine(strWidth,-530+2,430-2,-530+2,paint);        canvas.drawLine(430-2,-530+2,430-2,-strWidth,paint);        canvas.drawLine(430-2,-strWidth,strWidth,-strWidth,paint);        //这个i是高度/50 我在这写死了  同理x轴也是一样        for(int i=0;i<10;i++){//绘制横线            canvas.drawLine(0+strWidth,-50*i+(-strWidth),430,-50*i+(-strWidth),paint);        }        for(int i=1;i<8;i++){//绘制竖线            canvas.drawLine(50*i+strWidth,0-strWidth,50*i+strWidth,-530,paint);        }        for(int i=0;i<11;i++){//绘制y轴方向坐标            if(i==10){                canvas.drawText(50*i+"",0,-50*i-18,textPaint);            }else{                canvas.drawText(50*i+"",0,-50*i+(-25),textPaint);            }        }        for(int i=1;i<9;i++){//绘制x轴方向文字            if(i==8){                canvas.drawText(50*i+"",50*i+8,-10,textPaint);            }else{                canvas.drawText(50*i+"",50*i+20,-10,textPaint);            }        }    }    public void drawPoints(List<Point> points,Canvas canvas){        Path path = new Path();        boolean isStartPoint = false;        paint.setColor(Color.parseColor("#9ACD32"));        paint.setStrokeWidth(3);        if(points!=null){            for(Point point:points){                if(!isStartPoint){                    isStartPoint = true;                    path.moveTo(point.x+strWidth,-point.y-strWidth);                }else{                    path.lineTo(point.x+strWidth,-point.y-strWidth);                }            }            canvas.drawPath(path,paint);        }    }    /**     * 设置点的数据     * @param points     */    public void setDatas(List<Point> points){        this.mPoints = points;        invalidate();    }}
在外面使用:

package com.klineview;import android.graphics.Point;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private KLineView k_line_view;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        k_line_view = (KLineView) findViewById(R.id.k_line_view);        List<Point> mPoints = new ArrayList<>();        mPoints.add(new Point(20,30));        mPoints.add(new Point(100,200));        mPoints.add(new Point(130,280));        mPoints.add(new Point(200,90));        mPoints.add(new Point(240,300));        mPoints.add(new Point(300,360));        mPoints.add(new Point(350,210));        mPoints.add(new Point(390,60));        k_line_view.setDatas(mPoints);    }}
效果图:


在这还有一个要说明点,我不是从(0,0)点开始绘制的,是把(30,-30)当做(0,0)点,x,y轴都留了30px是要在x,y轴上绘制刻度的,所以在x轴上绘制点+30,在y轴上绘制点-30,就ok了!

2 0
原创粉丝点击