国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于Android 的餅圖組件設(shè)計

2019-10-22 06:36:42高毅王昕丁勇
現(xiàn)代計算機 2019年23期
關(guān)鍵詞:矩形圖表繪制

高毅,王昕,丁勇

(云南師范大學(xué)文理學(xué)院,昆明650222)

0 引言

隨著信息技術(shù)的飛速發(fā)展,人們對信息系統(tǒng)的需求越來越大。在大多數(shù)信息系統(tǒng)中,都存在報表功能,用圖表來向用戶展示數(shù)據(jù)。然而在Android 開發(fā)中,系統(tǒng)提供了文本框、編輯框、按鈕、單選按鈕與單選按鈕組、復(fù)選框、圖片框、下拉列表框、列表框、開關(guān)按鈕等大量的組件,雖能滿足大多數(shù)應(yīng)用的開發(fā)需求,但Android 系統(tǒng)并不提供圖表組件,開發(fā)人員只能創(chuàng)建自定義的圖表組件,以滿足用戶的特殊需求。

餅圖作為最為常用的圖表組件之一,在很多Android 應(yīng)用中都會使用到。然而,Android 系統(tǒng)中的餅圖組件的開源方案并不多,技術(shù)不夠成熟,或多或少都會存在一些問題,如使用不便、不夠靈活、用戶體驗差等。本文將從布局空間設(shè)計、餅圖的繪制流程、餅圖實現(xiàn)的核心代碼等方面來描述一種基于Android 的餅圖組件。該組件提供了很多屬性接口,方便用戶根據(jù)自身的需求來定制相應(yīng)的餅圖。該組件還實現(xiàn)了動畫效果,是按照順時針方向依次顯示各個數(shù)據(jù)項對應(yīng)的餅圖,用戶體驗好。

1 相關(guān)概念

1.1 餅圖

餅圖采用了餅干的隱喻,用環(huán)形方式呈現(xiàn)各分量在整體中的比例[1],是數(shù)據(jù)可視化的常用工具,通常用來顯示一個數(shù)據(jù)系列(數(shù)據(jù)系列:在圖表中繪制的相關(guān)數(shù)據(jù)點,這些數(shù)據(jù)源自數(shù)據(jù)表的行或列。圖表中的每個數(shù)據(jù)系列具有唯一的顏色或圖案并且在圖表的圖例中表示??梢栽趫D表中繪制一個或多個數(shù)據(jù)系列。餅圖只有一個數(shù)據(jù)系列。)中各項的大小與各項總和的比例。餅圖中的數(shù)據(jù)點(數(shù)據(jù)點:在圖表中繪制的單個值,這些值由條形、柱形、折線、餅圖或圓環(huán)圖的扇面、圓點和其他被稱為數(shù)據(jù)標(biāo)記的圖形表示。相同顏色的數(shù)據(jù)標(biāo)記組成一個數(shù)據(jù)系列。)顯示為整個餅圖的百分比。

1.2 View類

Android 應(yīng)用的絕大部分UI 組件都放在android.widget 包及其子包、android.view 包及其子包中,Android應(yīng)用的所有UI 組件都繼承了View 類?;贏ndroid UI 組件的實現(xiàn)原理,開發(fā)者完全可以開發(fā)出項目定制的組件,當(dāng)Android 系統(tǒng)提供的UI 組件不足以滿足需求時,可以通過繼承View 來派生自定義組件。過程為,首先定義一個繼承View 基類的子類,然后重寫View 類的一個或多個方法來實現(xiàn)[2]。

1.3 Canvas類

各類圖形是要在一張畫布上繪制的,Canvas 類則實現(xiàn)了畫布這一功能,在繪制圖形之前,需要對Canvas設(shè)置一些畫布的屬性,如畫布的顏色、尺寸等[2]。

1.4 Paint類

要實現(xiàn)繪圖功能,首先需要畫筆工具,Paint 類便是Android 的畫筆,它包含了繪制幾何圖形、文本和位圖所需的一些風(fēng)格和顏色信息,如線寬、字體和大小等。通過Paint 類提供給用戶的公共方法,可以對其屬性進行設(shè)置[2]。

2 餅圖組件的設(shè)計與實現(xiàn)

2.1 布局空間設(shè)計及計算

在實現(xiàn)餅圖組件時,布局空間的設(shè)計尤為關(guān)鍵。移動端應(yīng)用開發(fā)最大的特點之一就是可用顯示空間小,要讓餅圖有更好的顯示效果,必需要合理的分配布局空間。餅圖的布局空間設(shè)計如圖1 所示,由圖表標(biāo)題區(qū)、圖表繪制區(qū)和系列標(biāo)題區(qū)構(gòu)成[3-4]。其中,圖表標(biāo)題區(qū)用來顯示餅圖的總標(biāo)題,圖表繪制區(qū)用來顯示餅圖,系列標(biāo)題區(qū)用來顯示餅圖的系列標(biāo)題。而餅圖的系列一般會存在多個,那系列標(biāo)題也就存在多個,為了更好的利用布局空間,本文設(shè)計的方案是每一行顯示兩個系列標(biāo)題,依次從左到右。在餅圖的設(shè)計過程中,為了能讓Android 開發(fā)人員可以自定義標(biāo)題文本字體大小,首先計算該餅圖在移動設(shè)備端的顯示大小,再計算系列標(biāo)題區(qū)所占大小,最后得到圖表繪制區(qū)的大小。下面就計算過程做詳細(xì)描述,單位都為像素(px)。

圖1 布局空間設(shè)計圖

(1)計算餅圖在移動設(shè)備端顯示的大小

用W 表示餅圖在移動端設(shè)備上所占的寬度,H 表示餅圖在移動端設(shè)備上所占的高度。通過重寫View類中的onMeasure 方法來實現(xiàn)對W 和H 的計算。關(guān)鍵代碼如下:

//計算顯示模式

int specMode=MeasureSpec.getMode(widthMeasureSpec);

//計算寬度

int width=MeasureSpec.getSize(widthMeasureSpec);

//若顯示模式是不確定的值,或者未指定尺寸,設(shè)置一個300 的默認(rèn)值

if(specMode==MeasureSpec.UNSPECIFIED)

{

width=300;

}

//計算高度的代碼和上面計算寬度的代碼類似,在此省略

......

setMeasuredDimension(width,height);

編寫好上面的onMeasure 方法后,就可以通過以下公式來計算W 和H。

W=getMeasuredWidth() (1)

H=getMeasuredHeight() (2)

(2)計算系列標(biāo)題區(qū)的大小

為了計算系列標(biāo)題區(qū)所占空間的寬和高,特地編寫了private Rect getTextRect(String text,float textSize)方法,該方法有兩個參數(shù),第一個參數(shù)text 是顯示文本的內(nèi)容,第2 個參數(shù)textSize 是顯示文本的大小,返回值是Rect 類型的對象。由于中文的基線和英文的基線不一樣,為了顯示效果,在計算文本所占矩形時做了修正。關(guān)鍵代碼如下:

Paint.FontMetricsInt fm=paint.getFontMetricsInt();

//修正上邊界,減去文本大小的四分之一

int top=baseLineY+fm.top-(int)(textSize/4.0f);

//修正下邊界,加上文本大小的四分之一

int bottom=baseLineY+fm.bottom+(int)(textSize/4.0f);

//計算文本所占矩形空間的寬度

int width=(int)paint.measureText(text);

Rect rect=new Rect(baseLineX,top,baseLineX+width,bottom);

編寫好上面的getTextRect 方法后,就可以計算系列標(biāo)題區(qū)所占空間的寬和高。

本文設(shè)計的餅圖系列標(biāo)題區(qū)是一行顯示兩個標(biāo)題,可顯示多個系列標(biāo)題。系列標(biāo)題區(qū)的寬WST和高HST計算公式如下:

WST=(getTextRect(系列標(biāo)題文本內(nèi)容,系列標(biāo)題文本大小).width())*2 (3)

HST=(getTextRect(系列標(biāo)題文本內(nèi)容,系列標(biāo)題文本大?。?height())*(Integer)(n/2) (4)

其中,n 表示系列標(biāo)題的數(shù)目,(Integer)(n/2)表示對表達式n/2 進行取整運算。

(3)計算圖表繪制區(qū)的大小

圖表繪制區(qū)的寬WC和高HC計算公式如下:

WC=W (5)

HC=H-HST(6)

然而,在餅圖的實現(xiàn)過程中,要對圖表繪制區(qū)的大小做修正,這和在一個矩形中畫內(nèi)切圓同理。當(dāng)矩形是一個正方形時,圖表繪制區(qū)占了整個矩形;當(dāng)矩形的寬大于高時,圖表繪制區(qū)的左右兩側(cè)會有空白區(qū)域,這時餅圖的最大半徑為矩形高的一半;當(dāng)矩形的寬小于高時,圖表繪制區(qū)的上下兩端會有空白區(qū)域,這時餅圖的最大半徑為矩形寬的一半。所以,圖表區(qū)的真實大小是由圖表繪制區(qū)的寬和高的最小值決定的。

修正的圖表繪制區(qū)的寬WC'和高HC'計算公式如下:

WC'=HC'=MIN(WC,HC) (7)

其中,MIN(WC,HC)表示計算WC和HC的最小值。

2.2 餅圖繪制的實現(xiàn)

在Android 系統(tǒng)中實現(xiàn)自定義組件,需要繼承View 類,重寫其中的一個或者多個方法,其中對on-Draw 方法的重寫尤為重要。本文描述的餅圖組件是有動畫效果的,在繪制過程中把背景的繪制和圖表區(qū)的繪制分開,這樣有利于控制圖表區(qū)的動畫效果。下面先介紹繪制流程,再對onDraw 方法中的核心代碼做描述。

(1)繪制流程

餅圖的繪制流程如圖2 所示。首先取系列數(shù)據(jù)、設(shè)置圖表屬性,然后根據(jù)系列數(shù)據(jù)和圖表屬性去計算與繪制餅圖相關(guān)的屬性值,接著繪制背景,給屬性動畫的監(jiān)聽變量animatedValue 設(shè)置初值為0,接下來去判斷animatedValue 的值是否小于等于1,若成立,重繪餅圖,并計算變量animatedValue 新的監(jiān)聽值,接著返回去判斷animatedValue 的值是否小于等于1,否則,繪制過程結(jié)束。

圖2 繪制流程圖

(2)onDraw 方法的核心代碼

重寫onDraw 方法的核心代碼如下:

//計算圖表區(qū)的寬和高

contentWidth=mRight-mLeft;

contentHeight=mBottom-mTop;

//計算圖表區(qū)的中心點

centerX=mLeft+contentWidth/2.0f;

centerY=mTop+contentHeight/2.0f;

//設(shè)置畫筆對象

piePaint=new Paint(Paint.ANTI_ALIAS_FLAG);

piePaint.setStyle(Paint.Style.FILL_AND_STROKE);

//修正圖表區(qū)的寬和高

if(contentWidth<=contentHeight){

oval=new RectF(centerX-contentWidth/2.0f,centerYcontentWidth/2.0f,

centerX+contentWidth/2.0f,centerY+contentWidth/2.0f);

}

else{

oval=new RectF(centerX-contentHeight/2.0f,center Y-contentHeight/2.0f,

centerX+contentHeight/2.0f,centerY+contentHeight/2.0f);

}

//設(shè)置繪制的初始角度

float currentx=0;

//遍歷數(shù)據(jù)角度系列值

for(int i=0;i

//若屬性動畫值乘上360 大于等于初始角度,則重繪圖表內(nèi)容

if(animatedValue*360)>=currentx){

//設(shè)置畫筆對象顏色屬性

piePaint.setARGB(seriesItemColor.get(i%seriesItemColor.size()).getA(),

seriesItemColor.get(i%seriesItemColor.size()).getR(),

seriesItemColor.get(i%seriesItemColor.size()).getG(),

seriesItemColor.get(i%seriesItemColor.size()).getB());

//繪制扇形

canvas.drawArc(oval,currentx,Math.min(seriesAngleValue.get(i),(animatedValue*360)-currentx)-1,true,pie-Paint);

//計算新的初始角度

currentx=currentx+seriesAngleValue.get(i);

}

}

3 實驗效果

本文實現(xiàn)的餅圖組件的效果如圖3 和圖4 所示。該組件可以顯示系列中不同數(shù)據(jù)項的比例,不同的數(shù)據(jù)項用不同的顏色表示,還具有動畫效果,動畫效果為順時針方向依次顯示系列的數(shù)據(jù)項。餅圖組件在設(shè)計的過程中,加入了大量的屬性作為類的數(shù)據(jù)成員,并編寫了相應(yīng)的set 方法和get 方法,方便用戶根據(jù)自身的需求去設(shè)置圖表樣式,如背景顏色、餅圖邊緣線條粗細(xì)、餅圖邊緣線條顏色、文本大小、文本顏色等屬性。相比現(xiàn)有的類似的第三方開源方案,該餅圖組件使用方便、靈活,所以,該組件還是具有一定的創(chuàng)新性,并具備一定的實用價值。

圖3 實驗效果圖一

圖4 實驗效果圖二

4 結(jié)語

本文分別布局空間設(shè)計、餅圖組件的繪制流程、on-Draw 方法的核心代碼等方面對餅圖組組件進行描述,實現(xiàn)的餅圖組件可以用來解決Android 開發(fā)中數(shù)據(jù)展示的一些問題。經(jīng)過測試,顯示效果良好,布局空間設(shè)計合理,運行效率高,動畫效果良好,用戶體驗好,能滿足大多數(shù)Android 應(yīng)用開發(fā)人員的需求。但是,還是有一些方面需要進一步研究,如環(huán)形圖、南丁格爾玫瑰圖、嵌套餅圖,等等,下一步將會在這些方面做深入研究。

猜你喜歡
矩形圖表繪制
Art on coffee cups
兩矩形上的全偏差
化歸矩形證直角
放學(xué)后
童話世界(2018年17期)2018-07-30 01:52:02
從矩形內(nèi)一點說起
雙周圖表
足球周刊(2016年14期)2016-11-02 10:54:56
雙周圖表
足球周刊(2016年15期)2016-11-02 10:54:16
雙周圖表
足球周刊(2016年10期)2016-10-08 18:30:55
圖表
世界博覽(2016年16期)2016-09-27 18:25:26
在轉(zhuǎn)變中繪制新藍(lán)圖
华安县| 奎屯市| 阿城市| 东兴市| 泸州市| 定陶县| 竹山县| 霸州市| 九台市| 宝兴县| 大宁县| 青铜峡市| 贵港市| 周至县| 绩溪县| 山丹县| 左权县| 五华县| 广南县| 黑山县| 陵水| 汶川县| 汕尾市| 临泉县| 巴林右旗| 江源县| 深州市| 福泉市| 陆川县| 舟山市| 吉木萨尔县| 隆尧县| 宁河县| 达州市| 沂水县| 赫章县| 鲜城| 滨海县| 南召县| 资兴市| 三亚市|