![【移動應(yīng)用開發(fā)技術(shù)】怎么在Android中通過自定義控件實現(xiàn)一個折線圖_第1頁](http://file4.renrendoc.com/view/7078c34b11805ab5e351bd536c6f3774/7078c34b11805ab5e351bd536c6f37741.gif)
![【移動應(yīng)用開發(fā)技術(shù)】怎么在Android中通過自定義控件實現(xiàn)一個折線圖_第2頁](http://file4.renrendoc.com/view/7078c34b11805ab5e351bd536c6f3774/7078c34b11805ab5e351bd536c6f37742.gif)
![【移動應(yīng)用開發(fā)技術(shù)】怎么在Android中通過自定義控件實現(xiàn)一個折線圖_第3頁](http://file4.renrendoc.com/view/7078c34b11805ab5e351bd536c6f3774/7078c34b11805ab5e351bd536c6f37743.gif)
![【移動應(yīng)用開發(fā)技術(shù)】怎么在Android中通過自定義控件實現(xiàn)一個折線圖_第4頁](http://file4.renrendoc.com/view/7078c34b11805ab5e351bd536c6f3774/7078c34b11805ab5e351bd536c6f37744.gif)
![【移動應(yīng)用開發(fā)技術(shù)】怎么在Android中通過自定義控件實現(xiàn)一個折線圖_第5頁](http://file4.renrendoc.com/view/7078c34b11805ab5e351bd536c6f3774/7078c34b11805ab5e351bd536c6f37745.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】怎么在Android中通過自定義控件實現(xiàn)一個折線圖
這篇文章給大家介紹怎么在Android中通過自定義控件實現(xiàn)一個折線圖,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。Android是一種基于Linux內(nèi)核的自由及開放源代碼的操作系統(tǒng),主要使用于移動設(shè)備,如智能手機和平板電腦,由美國Google公司和開放手機聯(lián)盟領(lǐng)導(dǎo)及開發(fā)。首先是控件繪圖區(qū)域的劃分,控件左邊取一小部分(控件總寬度的八分之一)繪制表頭,右邊剩余的部分繪制表格確定表格的行列數(shù),首先繪制一個三行八列的網(wǎng)格,設(shè)置好行列的坐標(biāo)后開始繪制/*繪制三條橫線*/
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);
}網(wǎng)格繪制完成后,開始繪制折線圖根據(jù)輸入的節(jié)點數(shù)據(jù),分別繪制兩條折線通過canvas的drawLine方法依次連接兩點即可在每個數(shù)據(jù)節(jié)點處繪制一個小圓,突出顯示/*繪制第一條折線的路徑*/
for
(int
i
=
0;
i
<
mPerformance_1.length
-
1;
i++)
{
/*折線圖的折線的畫筆設(shè)置粗一點*/
mPaintLine.setStrokeWidth(5);
/*計算當(dāng)前節(jié)點的坐標(biāo)值*/
float
prePointX
=mLineXs[i];
float
prePointY
=mLineYs[2]
-
(mLineYs[2]
-
mLineYs[mPerformance_1[i].type])
*
animCurrentValue;
/*計算下一個節(jié)點的坐標(biāo)值*/
float
nextPointX=mLineXs[i
+
1];
float
nextPointY=mLineYs[2]
-
(mLineYs[2]
-
mLineYs[mPerformance_1[i
+
1].type])
*
animCurrentValue;
/*連接當(dāng)前坐標(biāo)和下一個坐標(biāo),繪制線段*/
canvas.drawLine(prePointX,
prePointY,
nextPointX,
nextPointY,
mPaintLine1);
/*當(dāng)前節(jié)點坐標(biāo)處繪制小圓*/
canvas.drawCircle(prePointX,
prePointY,
mSmallDotRadius,
mPointPaint);
}兩條折線重合的地方,需要特殊考慮,比如希望兩條折線重合的地方折線變?yōu)榘咨O(shè)置下兩條折線的畫筆即可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();
/*動畫刷新的次數(shù)*/
private
int
mDuration
=
10;
/*當(dāng)前動畫進度值*/
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();
/*坐標(biāo)點的小圓點畫筆*/
private
Paint
mPointPaint
=
new
Paint();
private
float
mSmallDotRadius
=
4;
private
TypedValue
typedValue;
private
int
mPaintClolor;
/*Handler刷新界面產(chǎn)生動畫效果*/
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();
}
}
/**
*
設(shè)置折線1的顏色
*
*
@param
mLineColor1
*/
public
void
setLineColor1(int
mLineColor1)
{
this.mLineColor1
=
mLineColor1;
}
/**
*
設(shè)置折線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;
/*一共三行,設(shè)置每一行的垂直坐標(biāo)*/
float[]
mLineYs
=
new
float[]{totalHeight
/
8,
totalHeight
/
2,
totalHeight
*
7
/
8};
/*一共八列,設(shè)置每一列的水平坐標(biāo)*/
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("負(fù)場",
textWide
/
2,
mLineYs[2]
+
textBaseLineOffset,
mPaintText);
/*繪制表格畫筆設(shè)置*/
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);
}
/*折線圖畫筆設(shè)置*/
mPaintLine1.setStyle(Paint.Style.STROKE);
/*設(shè)置透明度,取值范圍為0~255,數(shù)值越小越透明,0表示完全透明*/
mPaintLine1.setAlpha(0);
mPaintLine1.setAntiAlias(true);
mPaintLine1.setColor(mLineColor1);
mPaintLine1.setStrokeWidth(5);
mPaintLine2.setStyle(Paint.Style.STROKE);
/*設(shè)置透明度,取值范圍為0~255,數(shù)值越小越透明,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));
}
/*畫節(jié)點處的小圓點的畫筆設(shè)置*/
mPointPaint.setStyle(Paint.Style.STROKE);
mPointPaint.setAntiAlias(true);
mPointPaint.setColor(mPaintClolor);
/*計算當(dāng)前動畫進度對應(yīng)的數(shù)值*/
float
animCurrentValue
=
mDecelerateInterpolator.getInterpolation(1.0f
*
mCurrentTime
/
mDuration);
mPaintLine.setColor(mLineColor1);
/*繪制第一條折線的路徑*/
for
(int
i
=
0;
i
<
mPerformance_1.length
-
1;
i++)
{
/*折線圖的折線的畫筆設(shè)置粗一點*/
mPaintLine.setStrokeWidth(5);
/*計算當(dāng)前節(jié)點的坐標(biāo)值*/
float
prePointX
=mLineXs[i];
float
prePointY
=mLineYs[2]
-
(mLineYs[2]
-
mLineYs[mPerformance_1[i].type])
*
animCurrentValue;
/*計算下一個節(jié)點的坐標(biāo)值*/
float
nextPointX=mLineXs[i
+
1];
float
nextPointY=mLineYs[2]
-
(mLineYs[2]
-
mLineYs[mPerformance_1[i
+
1].type])
*
animCurrentValue;
/*連接當(dāng)前坐標(biāo)和下一個坐標(biāo),繪制線段*/
canvas.drawLine(prePointX,
prePointY,
nextPointX,
nextPointY,
mPaintLine1);
/*當(dāng)前節(jié)點坐標(biāo)處繪制小圓*/
canvas.drawCircle(prePointX,
prePointY,
mSmallDotRadius,
mPointPaint);
}
/*第一個折線圖的最后一個節(jié)點的坐標(biāo)*/
float
lastPointX=mLineXs[mPerformance_1.length
-
1];
float
lastPointY=
mLineYs[2]
-
(mLineYs[2]
-
mLineYs[mPerformance_1[mPerformance_1.length
-
1].type])
*
animCurrentValue;
/*繪制最后一個節(jié)點的外圍小圓*/
canvas.drawCirc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年巴音郭楞道路運輸從業(yè)資格證考試內(nèi)容是什么
- 小學(xué)三年級100道口算題
- 2025年欽州貨運上崗證模擬考試題
- 2025年荷澤貨運從業(yè)資格證模擬考試駕考
- 華東師大版七年級數(shù)學(xué)上冊《第3章整式的加減3.1列代數(shù)式3.1.3列代數(shù)式 》聽評課記錄
- 湘教版數(shù)學(xué)八年級下冊《2.2.1平行四邊形的邊、角性質(zhì)》聽評課記錄
- 建筑項目經(jīng)理工作總結(jié)
- 初中理科教研組工作計劃
- 新學(xué)校校辦室工作計劃
- 平面設(shè)計師工作計劃范文欣賞
- 裝配式混凝土結(jié)構(gòu)施工技術(shù)講課課件
- 小型屠宰場可行性研究報告
- 急性呼吸道感染護理查房課件
- 物業(yè)品質(zhì)檢查標(biāo)準(zhǔn)及評分細則
- 密閉取芯完整
- 2023年敬老院重陽節(jié)老年人活動策劃方案通用
- 2023年09月內(nèi)蒙古赤峰學(xué)院招考聘用“雙師型”教師2人筆試歷年難易錯點考題薈萃附帶答案詳解
- 高考語文復(fù)習(xí):文言文簡答題例析
- 三年級英語上冊整冊書單詞默寫表學(xué)生版(外研版三起)
- 課本劇《劉姥姥進大觀園》劇本
- 《研學(xué)旅行概論》課程標(biāo)準(zhǔn)
評論
0/150
提交評論