Android实现折线走势图

本文实例为大家分享了Android折线走势图的具体代码,供大家参考,具体内容如下

先来看看效果图

可以根据球的数量动态的改变自己的球半径,以及线宽

代码实现也是超级简单

//获取自定义属性

private void obtainStyledAttrs(AttributeSet attrs) {

TypedArray typedArray = getContext().obtainStyledAttributes(attrs,R.styleable.High_LowChartView);

mTextSize = (int)typedArray.getDimension(R.styleable.High_LowChartView_hl_chart_textsize,mTextSize);

mTextColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_textcolor,mTextColor);

if (typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text)!=null){

mHighText = typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text);

}

if(typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text)!=null){

mLowText = typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text);

}

mHighPointColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_high_pointcolor,mHighPointColor);

mLowPointColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_low_pointcolor,mLowPointColor);

mMainLineColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_mianlinecolor,mMainLineColor);

mChartLineColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_chartlinecolor,mChartLineColor);

mChartDistance = (int) typedArray.getDimension(R.styleable.High_LowChartView_hl_chart_distance,mChartDistance);

init();

typedArray.recycle();

}

//重写onMeasure

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = measureHeight(heightMeasureSpec);

setMeasuredDimension(width,height);

}

//计算view需要的高度

private int measureHeight(int heightMeasureSpec) {

int result = 0;

int mode = MeasureSpec.getMode(heightMeasureSpec);

int size = MeasureSpec.getSize(heightMeasureSpec);

if(mode == MeasureSpec.EXACTLY){//如果给了具体值则直接用

result=size;

}else {

//否则高度等于字高与球直径的最大值

textHeight = (mPaint.descent()-mPaint.ascent());

float halfHeight = Math.max(textHeight, mPointMaxHeight) / 2;

result = (int) (halfHeight+mChartDistance);

//如果模式为AT_MOST即:测量高度不能超过父类给定的高度则取测量结果与size的最小值

if(mode==MeasureSpec.AT_MOST){

result = Math.min(result,size);

}

}

return result;

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if(!initMeasure()) return;

canvas.save();

//1先画两条主线

mPaint.setColor(mMainLineColor);

mPaint.setStrokeWidth(mainLineHeight);

//high Line

canvas.drawLine(textWidth+DEFAULT_OFFSETTING,mainLinePosition,w,mainLinePosition,mPaint);

//low Line

canvas.drawLine(textWidth+DEFAULT_OFFSETTING,mainLinePosition+mChartDistance,w,mainLinePosition+mChartDistance,mPaint);

//2再画文字

mPaint.setColor(mTextColor);

mPaint.setTextAlign(Paint.Align.LEFT);

Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();

RectF rt1=new RectF(0,mainLinePosition-textHeight/2,w,mainLinePosition+textHeight/2);

int baseline = (int) ((rt1.bottom + rt1.top - fontMetrics.bottom - fontMetrics.top) / 2);

canvas.drawText(mHighText,0,baseline,mPaint);

canvas.drawText(mLowText,0,baseline+mChartDistance,mPaint);

//3初始化小球圆心

canvas.translate(textWidth+DEFAULT_OFFSETTING,0);

for (int i=0;i<mPointNum;i++){

//high point

if (mList.get(i).isHighPoint){

// mPaint.setColor(mHighPointColor);

// canvas.drawCircle((pointHeight/2+offsetX)+i*(pointHeight+offsetX), mainLinePosition, pointHeight/2, mPaint);

//存入小球的圆心坐标

mList.get(i).setXY((pointHeight/2+offsetX)+i*(pointHeight+offsetX),mainLinePosition);

}else {

//low point

// mPaint.setColor(mLowPointColor);

// canvas.drawCircle((pointHeight/2+offsetX)+i*(pointHeight+offsetX), mainLinePosition+mChartDistance, pointHeight/2, mPaint);

mList.get(i).setXY((pointHeight/2+offsetX)+i*(pointHeight+offsetX),mainLinePosition+mChartDistance);

}

}

//4连接小球

if(mList.size()>=2){

mPaint.setColor(mChartLineColor);

mPaint.setStrokeWidth(chartLineWidth);

for (int i=0;i<mPointNum-1;i++){

canvas.drawLine(mList.get(i).cx,mList.get(i).cy,mList.get(i+1).cx,mList.get(i+1).cy,mPaint);

}

}

//5绘制小球(为了不让线遮盖小球)

for (int i=0;i<mPointNum;i++){

//high point

if (mList.get(i).isHighPoint){

mPaint.setColor(mHighPointColor);

//low point

}else {

mPaint.setColor(mLowPointColor);

}

canvas.drawCircle(mList.get(i).cx, mList.get(i).cy, pointHeight/2, mPaint);

}

canvas.restore();

}

/**

* 根据小球数量去动态测量一些属性

* @return

*/

private boolean initMeasure() {

//根据传进来的point数量计算小点的大小,MainLine的线宽,折线的线宽

/* 如果小球数量在1-10个,主线高度为3dip

* 如果小球数量在10-20个,主线高度设置为2dip

* 如果小球数量超过20个,主线高度设置为1dp

*/

mPointNum=mList.size();

// if(mPointNum==0) return false;

if(10>mPointNum){

mainLineHeight=dp2px(3);

}else if(10<=mPointNum&&20>mPointNum){

mainLineHeight = dp2px(2);

}else {

mainLineHeight = dp2px(1);

}

//主线长度等于总宽度-(文字宽度+30px)

textWidth=Math.max(mPaint.measureText(mHighText),mPaint.measureText(mLowText));

mainLineWidth = (int) (w-(textWidth+DEFAULT_OFFSETTING));

/*小球直径应该由主线长度与小球数量决定*/

//理想直径

float ideaDia = mainLineWidth / (mPointNum + (mPointNum + 1));

//小球直径不能大于最大直径

if(ideaDia>mPointMaxHeight){

// Log.i("TTT","ideaDia>mPointMaxHeight");

pointHeight = mPointMaxHeight;

offsetX=(mainLineWidth-mPointNum*pointHeight)/(mPointNum+1);

//(极端情况)如果小球直径小于线高,为小球直径+2px

}else if(ideaDia<=mainLineHeight){

// Log.i("TTT","ideaDia<=mPointMaxHeight");

pointHeight = mainLineHeight+2;

offsetX=(mainLineWidth-mPointNum*pointHeight)/(mPointNum+1);

}else {

// Log.i("TTT"," pointHeight=offsetX=ideaDia");

pointHeight=offsetX=ideaDia;

}

//主线位置

mainLinePosition = (h-mChartDistance)/2;

//折线宽度

chartLineWidth = mainLineHeight/2;

return true;

}

//刷新小球集合

public void setPointList(List<AiyingPoint> list){

if (list==null&&list.size()==0) return;

mList.clear();

if (list.size()>150) {

mList.addAll(list.subList(0,150));

} else {

mList.addAll(list);

}

invalidate();

}

使用示例

<com.android.view.High_LowChartView

android:id="@+id/hl_chart"

android:layout_below="@+id/tv_state"

android:layout_marginLeft="15dp"

android:layout_marginRight="15dp"

android:layout_width="match_parent"

android:layout_height="70dp"

app:hl_chart_mianlinecolor="#CDCDCD"

app:hl_chart_distance="55dp"

app:hl_chart_low_pointcolor="#999999"

app:hl_chart_high_pointcolor="#F70919"

app:hl_chart_textsize="13sp"

app:hl_chart_textcolor="#2f2f2f"

app:hl_chart_chartlinecolor="#999999"

/>

好了这样折线图就绘制完成了,是不是很简单呢?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android实现折线走势图 的全部内容, 来源链接: utcz.com/p/242202.html

回到顶部