【移动应用开发技术】怎么在Android中通过自定义控件实现一个折线图_第1页
【移动应用开发技术】怎么在Android中通过自定义控件实现一个折线图_第2页
【移动应用开发技术】怎么在Android中通过自定义控件实现一个折线图_第3页
【移动应用开发技术】怎么在Android中通过自定义控件实现一个折线图_第4页
【移动应用开发技术】怎么在Android中通过自定义控件实现一个折线图_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】怎么在Android中通过自定义控件实现一个折线图

这篇文章给大家介绍怎么在Android中通过自定义控件实现一个折线图,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。首先是控件绘图区域的划分,控件左边取一小部分(控件总宽度的八分之一)绘制表头,右边剩余的部分绘制表格确定表格的行列数,首先绘制一个三行八列的网格,设置好行列的坐标后开始绘制/*绘制三条横线*/

for(int

i=0;i<3;i++){

canvas.drawLine(textWide,

mLineYs[i],

totalWidth,

mLineYs[i],

mPaintLine);

}

/*绘制八条竖线*/

for(int

i=0;i<8;i++){

canvas.drawLine(mLineXs[i],

0,

mLineXs[i],

totalHeight,

mPaintLine);

}网格绘制完成后,开始绘制折线图根据输入的节点数据,分别绘制两条折线通过canvas的drawLine方法依次连接两点即可在每个数据节点处绘制一个小圆,突出显示/*绘制第一条折线的路径*/

for

(int

i

=

0;

i

<

mPerformance_1.length

-

1;

i++)

{

/*折线图的折线的画笔设置粗一点*/

mPaintLine.setStrokeWidth(5);

/*计算当前节点的坐标值*/

float

prePointX

=mLineXs[i];

float

prePointY

=mLineYs[2]

-

(mLineYs[2]

-

mLineYs[mPerformance_1[i].type])

*

animCurrentValue;

/*计算下一个节点的坐标值*/

float

nextPointX=mLineXs[i

+

1];

float

nextPointY=mLineYs[2]

-

(mLineYs[2]

-

mLineYs[mPerformance_1[i

+

1].type])

*

animCurrentValue;

/*连接当前坐标和下一个坐标,绘制线段*/

canvas.drawLine(prePointX,

prePointY,

nextPointX,

nextPointY,

mPaintLine1);

/*当前节点坐标处绘制小圆*/

canvas.drawCircle(prePointX,

prePointY,

mSmallDotRadius,

mPointPaint);

}两条折线重合的地方,需要特殊考虑,比如希望两条折线重合的地方折线变为白色设置下两条折线的画笔即可mPaintLine2.setXfermode(new

PorterDuffXfermode(PorterDuff.Mode.SCREEN));

mPaintLine1.setXfermode(new

PorterDuffXfermode(PorterDuff.Mode.SCREEN));测试代码及效果;final

Random

random=new

Random();

final

LineChartView

myView=(LineChartView)findViewById(R.id.custom_view);

final

LineChartView.Performance[]

performances1=new

LineChartView.Performance[8];

final

LineChartView.Performance[]

performances2=new

LineChartView.Performance[8];

myView.setOnClickListener(new

View.OnClickListener(){

@Override

public

void

onClick(View

v){

for(int

i=0;i<performances1.length;i++){

switch

(random.nextInt(2016)%3){

case

0:

performances1[i]=

LineChartView.Performance.WIN;

break;

case

1:

performances1[i]=

LineChartView.Performance.DRAW;

break;

case

2:

performances1[i]=

LineChartView.Performance.LOSE;

break;

default:

performances1[i]=

LineChartView.Performance.LOSE;

break;

}

switch

(random.nextInt(2016)%3){

case

0:

performances2[i]=

LineChartView.Performance.WIN;

break;

case

1:

performances2[i]=

LineChartView.Performance.DRAW;

break;

case

2:

performances2[i]=

LineChartView.Performance.LOSE;

break;

default:

performances1[i]=

LineChartView.Performance.LOSE;

break;

}

}

myView.setPerformances(performances1,performances2);

}

});完整代码如下:public

class

LineChartView

extends

View

{

private

Context

context;

/*动画插值器*/

DecelerateInterpolator

mDecelerateInterpolator

=

new

DecelerateInterpolator();

/*动画刷新的次数*/

private

int

mDuration

=

10;

/*当前动画进度值*/

private

int

mCurrentTime

=

0;

private

Performance[]

mPerformance_1,

mPerformance_2;

/*两条折线的颜色*/

private

int

mLineColor1,

mLineColor2;

/*绘制表头文字画笔*/

private

Paint

mPaintText

=

new

Paint();

/*绘制表格的画笔*/

private

Paint

mPaintLine

=

new

Paint();

/*第一条折线的画笔*/

private

Paint

mPaintLine1

=new

Paint();

/*第二条折线的画笔*/

private

Paint

mPaintLine2

=new

Paint();

/*坐标点的小圆点画笔*/

private

Paint

mPointPaint

=

new

Paint();

private

float

mSmallDotRadius

=

4;

private

TypedValue

typedValue;

private

int

mPaintClolor;

/*Handler刷新界面产生动画效果*/

private

Handler

mHandler

=

new

Handler();

private

Runnable

mAnimation

=

new

Runnable()

{

@Override

public

void

run()

{

if

(mCurrentTime

<

mDuration)

{

mCurrentTime++;

LineChartView.this.invalidate();

}

}

};

public

LineChartView(Context

context)

{

super(context);

this.context=context;

init();

}

public

LineChartView(Context

context,

AttributeSet

attrs)

{

super(context,

attrs);

this.context=context;

init();

}

public

LineChartView(Context

context,

AttributeSet

attrs,

int

defStyleAttr)

{

super(context,

attrs,

defStyleAttr);

this.context=context;

init();

}

public

enum

Performance

{

WIN(0),

DRAW(1),

LOSE(2);

public

int

type;

Performance(int

type)

{

this.type

=

type;

}

}

public

void

setPerformances(Performance[]

performance1,

Performance[]

performance2)

{

if

(performance1

==

null)

{

performance1

=

new

Performance[0];

}

if

(performance2

==

null)

{

performance2

=

new

Performance[0];

}

mPerformance_1

=

Arrays.copyOf(performance1,

performance1.length

>

8

?

8

:

performance1.length);

mPerformance_2

=

Arrays.copyOf(performance2,

performance2.length

>

8

?

8

:

performance2.length);

if

(isShown())

{

mCurrentTime

=

0;

this.invalidate();

}

}

/**

*

设置折线1的颜色

*

*

@param

mLineColor1

*/

public

void

setLineColor1(int

mLineColor1)

{

this.mLineColor1

=

mLineColor1;

}

/**

*

设置折线2的颜色

*

*

@param

mLineColor2

*/

public

void

setLineColor2(int

mLineColor2)

{

this.mLineColor2

=

mLineColor2;

}

private

void

init()

{

mLineColor1=Color.BLUE;

mLineColor2

=

Color.GREEN;

typedValue=new

TypedValue();

context.getTheme().resolveAttribute(R.attr.title_bar,typedValue,true);

mPaintClolor

=getResources().getColor(typedValue.resourceId);

final

LineChartView.Performance[]

performances1=new

LineChartView.Performance[8];

final

LineChartView.Performance[]

performances2=new

LineChartView.Performance[8];

final

Random

random=new

Random();

for(int

i=0;i<performances1.length;i++){

switch

(random.nextInt(2016)%3){

case

0:

performances1[i]=

LineChartView.Performance.WIN;

break;

case

1:

performances1[i]=

LineChartView.Performance.DRAW;

break;

case

2:

performances1[i]=

LineChartView.Performance.LOSE;

break;

default:

performances1[i]=

LineChartView.Performance.LOSE;

break;

}

switch

(random.nextInt(2016)%3){

case

0:

performances2[i]=

LineChartView.Performance.WIN;

break;

case

1:

performances2[i]=

LineChartView.Performance.DRAW;

break;

case

2:

performances2[i]=

LineChartView.Performance.LOSE;

break;

default:

performances1[i]=

LineChartView.Performance.LOSE;

break;

}

}

setPerformances(performances1,performances2);

}

/**

*

@param

canvas

*/

@Override

protected

void

onDraw(Canvas

canvas)

{

super.onDraw(canvas);

/*获取控件总宽高*/

float

totalWidth

=

getWidth();

float

totalHeight

=

getHeight();

/*左边取总宽度的八分之一绘制表格头部*/

float

textWide

=

totalWidth

/

8;

/*左边留一点空白*/

float

left_offset

=

10;

/*折线图的总宽度等于控件的总宽度减去表头和留白*/

float

chartWide

=

totalWidth

-

textWide

-

left_offset;

/*一共三行,设置每一行的垂直坐标*/

float[]

mLineYs

=

new

float[]{totalHeight

/

8,

totalHeight

/

2,

totalHeight

*

7

/

8};

/*一共八列,设置每一列的水平坐标*/

float[]

mLineXs

=

new

float[]{

textWide

+

left_offset

+

chartWide

*

0

/

8,

textWide

+

left_offset

+

chartWide

*

1

/

8,

textWide

+

left_offset

+

chartWide

*

2

/

8,

textWide

+

left_offset

+

chartWide

*

3

/

8,

textWide

+

left_offset

+

chartWide

*

4

/

8,

textWide

+

left_offset

+

chartWide

*

5

/

8,

textWide

+

left_offset

+

chartWide

*

6

/

8,

textWide

+

left_offset

+

chartWide

*

7

/

8,

};

/*绘制表头文字*/

mPaintText.setStyle(Paint.Style.FILL);

mPaintText.setColor(mPaintClolor);

mPaintText.setAlpha(226);

mPaintText.setTextSize(28);

/*从中间开始绘制*/

mPaintText.setTextAlign(Paint.Align.CENTER);

/*测量文字大小,并计算偏移量*/

Paint.FontMetrics

fontMetrics

=

mPaintText.getFontMetrics();

float

textBaseLineOffset

=

(fontMetrics.bottom

-

fontMetrics.top)

/

2

-

fontMetrics.bottom;

canvas.drawText("胜场",

textWide

/

2,

mLineYs[0]

+

textBaseLineOffset,

mPaintText);

canvas.drawText("平局",

textWide

/

2,

mLineYs[1]

+

textBaseLineOffset,

mPaintText);

canvas.drawText("负场",

textWide

/

2,

mLineYs[2]

+

textBaseLineOffset,

mPaintText);

/*绘制表格画笔设置*/

mPaintLine.setStyle(Paint.Style.STROKE);

mPaintLine.setAntiAlias(true);

mPaintLine.setColor(mPaintClolor);

mPaintLine.setAlpha(80);

mPaintLine.setStrokeWidth(1);

/*开始绘制表格*/

/*绘制三条横线*/

for(int

i=0;i<3;i++){

canvas.drawLine(textWide,

mLineYs[i],

totalWidth,

mLineYs[i],

mPaintLine);

}

/*绘制八条竖线*/

for(int

i=0;i<8;i++){

canvas.drawLine(mLineXs[i],

0,

mLineXs[i],

totalHeight,

mPaintLine);

}

/*折线图画笔设置*/

mPaintLine1.setStyle(Paint.Style.STROKE);

/*设置透明度,取值范围为0~255,数值越小越透明,0表示完全透明*/

mPaintLine1.setAlpha(0);

mPaintLine1.setAntiAlias(true);

mPaintLine1.setColor(mLineColor1);

mPaintLine1.setStrokeWidth(5);

mPaintLine2.setStyle(Paint.Style.STROKE);

/*设置透明度,取值范围为0~255,数值越小越透明,0表示完全透明*/

mPaintLine2.setAlpha(0);

mPaintLine2.setAntiAlias(true);

mPaintLine2.setColor(mLineColor2);

mPaintLine2.setStrokeWidth(5);

if

(typedValue.resourceId==R.color.white){

/*PorterDuff.Mode.SCREEN

上下层都显示。*/

mPaintLine2.setXfermode(new

PorterDuffXfermode(PorterDuff.Mode.SCREEN));

mPaintLine1.setXfermode(new

PorterDuffXfermode(PorterDuff.Mode.SCREEN));

}else

{

/*PorterDuff.Mode.DARKEN

上下层都显示。变暗*/

mPaintLine2.setXfermode(new

PorterDuffXfermode(PorterDuff.Mode.DARKEN));

mPaintLine1.setXfermode(new

PorterDuffXfermode(PorterDuff.Mode.DARKEN));

}

/*画节点处的小圆点的画笔设置*/

mPointPaint.setStyle(Paint.Style.STROKE);

mPointPaint.setAntiAlias(true);

mPointPaint.setColor(mPaintClolor);

/*计算当前动画进度对应的数值*/

float

animCurrentValue

=

mDecelerateInterpolator.getInterpolation(1.0f

*

mCurrentTime

/

mDuration);

mPaintLine.setColor(mLineColor1);

/*绘制第一条折线的路径*/

for

(int

i

=

0;

i

<

mPerformance_1.length

-

1;

i++)

{

/*折线图的折线的画笔设置粗一点*/

mPaintLine.setStrokeWidth(5);

/*计算当前节点的坐标值*/

float

prePointX

=mLineXs[i];

float

prePointY

=mLineYs[2]

-

(mLineYs[2]

-

mLineYs[mPerformance_1[i].type])

*

animCurrentValue;

/*计算下一个节点的坐标值*/

float

nextPointX=mLineXs[i

+

1];

float

nextPointY=mLineYs[2]

-

(mLineYs[2]

-

mLineYs[mPerformance_1[i

+

1].type])

*

animCurrentValue;

/*连接当前坐标和下一个坐标,绘制线段*/

canvas.drawLine(prePointX,

prePointY,

nextPointX,

nextPointY,

mPaintLine1);

/*当前节点坐标处绘制小圆*/

canvas.drawCircle(prePointX,

prePointY,

mSmallDotRadius,

mPointPaint);

}

/*第一个折线图的最后一个节点的坐标*/

float

lastPointX=mLineXs[mPerformance_1.length

-

1];

float

lastPointY=

mLineYs[2]

-

(mLineYs[2]

-

mLineYs[mPerformance_1[mPerformance_1.length

-

1].type])

*

animCurrentValue;

/*绘制最后一个节点的外围小圆*/

canvas.drawCirc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论