高毅,王昕,丁勇
(云南師范大學(xué)文理學(xué)院,昆明650222)
在進(jìn)行Android 應(yīng)用開發(fā)時,離不開應(yīng)用界面的設(shè)計,Android 系統(tǒng)本身提供了很多組件用于界面設(shè)計,常用的有文本框、編輯框、按鈕、單選按鈕與單選按鈕組、復(fù)選框、圖片框、下拉列表框、列表框、開關(guān)按鈕等。這些組件基本上能滿足大多數(shù)應(yīng)用的開發(fā)需求,但仍然有一些需求是滿足不了的,現(xiàn)今的大多數(shù)應(yīng)用離不開數(shù)據(jù)展示,尤其是移動端的開發(fā),需要用到圖表來向用戶展示數(shù)據(jù),而散點圖是其中最為常見的一種,但Android 系統(tǒng)本身并不提供散點圖組件,因此需要開發(fā)者來創(chuàng)建自定義的散點圖組件,以實現(xiàn)用戶的特殊需求。
然而,Android 系統(tǒng)中的散點圖組件的開源方案并不多,第三方的散點圖組件或多或少都存在一些問題,要么使用不便,要么不夠靈活,要么用戶體驗差。本文通過設(shè)計一個基于Android 的散點圖組件,實現(xiàn)了數(shù)據(jù)的可視化展示,該組件的實現(xiàn)繼承了View 類,重寫了多個方法,加入了好多的組件屬性作為類的數(shù)據(jù)成員,并編寫了get 方法和set 方法,豐富了散點圖組件的顯示樣式,根據(jù)ValueAnimator 對象值不斷的重繪散點圖,以實現(xiàn)動畫效果,增強(qiáng)了用戶體驗。
散點圖是指在回歸分析中,數(shù)據(jù)點在直角坐標(biāo)系平面上的分布圖,散點圖表示因變量隨自變量而變化的大致趨勢,據(jù)此可以選擇合適的函數(shù)對數(shù)據(jù)點進(jìn)行擬合。
用兩組數(shù)據(jù)構(gòu)成多個坐標(biāo)點,考察坐標(biāo)點的分布,判斷兩變量之間是否存在某種關(guān)聯(lián)或總結(jié)坐標(biāo)點的分布模式。散點圖將序列顯示為一組點。值由點在圖表中的位置表示。類別由圖表中的不同標(biāo)記表示。散點圖通常用于比較跨類別的聚合數(shù)據(jù)[1]。
Android 應(yīng)用的絕大部分UI 組件都放在android.widget 包及其子包、android. view 包及其子包中,Android 應(yīng)用的所有UI 組件都繼承了View 類,View 組件非常類似于Swing 編程的JPanel,它代表一個空白的矩形區(qū)域。
View 類還有一個重要的子類ViewGroup,但View-Group 通常作為其他組件的容器使用。Android 的所有UI 組件都是建立在View、ViewGroup 基礎(chǔ)上的,Android 采用了“組合器”設(shè)計模式來設(shè)計View 和View-Group:ViewGroup 是View 的子類,因此ViewGroup 也可以被當(dāng)成View 使用。對于一個Android 應(yīng)用的圖形用戶界面來說,ViewGroup 作為容器來盛裝其他組件,而ViewGroup 里除了可以包含普通View 組件之外,還可以再次包含ViewGroup 組件。
基于Android UI 組件的實現(xiàn)原理,開發(fā)者完全可以開發(fā)出項目定制的組件,當(dāng)Android 系統(tǒng)提供的UI組件不足以滿足需求時,可以通過繼承View 來派生自定義組件。過程為,首先定義一個繼承View 基類的子類,然后重寫View 類的一個或多個方法來實現(xiàn)[2]。
移動端應(yīng)用開發(fā)最大的特點之一就是可用顯示空間小,要讓有限的布局空間去展示更多數(shù)據(jù)和信息,所以散點圖組件的布局空間設(shè)計尤為關(guān)鍵。散點圖的布局空間設(shè)計如圖1 所示,由圖表標(biāo)題區(qū)、Y 軸區(qū)、X 軸區(qū)、空白區(qū)、系列標(biāo)題區(qū)和圖表繪制區(qū)組成,其中空白區(qū)并不繪制內(nèi)容,為了在水平方向上對稱,它的大小和Y 軸區(qū)大小一致[3-4]。在該組件的設(shè)計過程中,為了能讓Android 應(yīng)用開發(fā)者可以自由地去設(shè)置文本的大小,首先計算該組件在移動設(shè)備端的顯示大小,再計算Y軸區(qū)、X 軸區(qū)、空白區(qū)、系列標(biāo)題區(qū)所占大小,最后得到圖表繪制區(qū)的大小。
圖1 布局空間設(shè)計圖
本文實現(xiàn)的散點圖組件支持顯示多個系列值,為了區(qū)別不同的系列,不僅使用了不同的顏色,還使用了不同的形狀標(biāo)志。本文的散點圖組件支持的點標(biāo)志有8 種,分別為圓形、正方形、等邊三角形、菱形、正五邊形、正六邊形、十字形狀和五角星形。
在點標(biāo)志繪制過程中,圓形和正方形的繪制相對簡單,使用drawCircle 方法來繪制圓形,使用drawRect方法來繪制正方形。而其他六種點標(biāo)志的繪制相對復(fù)雜,需要用到Android 中的Path 方面的技術(shù)。下面先對Path 做一個簡單的介紹,然后介紹這六種點標(biāo)志的繪制過程。
(1)Path 類
在進(jìn)行畫線等操作時還需要連接路徑,這個工具由Path 提供,Path 類中包含一些直線或曲線連接到指定點的方法。Android 提供的Path 是一個非常有用的類,它可以預(yù)先在View 上將N 個點連成一條“路徑”,然后調(diào)用Canvas 的drawPath 方法即可沿著路徑繪制圖形。
(2)等邊三角形
在繪制等邊三角形時,首先固定一個中心點坐標(biāo)(centerX,center),在以width 的一半為半徑的圓上面計算出等邊三角形的3 個點的坐標(biāo),依次為(centerX,centerY-width/2)、(centerX+width/2,centerY+width/2)、(centerX-width/2,centerY+width/2),用Path 對象把這3 個點連接起來并閉合,就可以繪制出等邊三角形了。
(3)菱形
在繪制菱形時,首先固定一個中心點坐標(biāo)(centerX,center),在以width 的一半為半徑的圓上面計算出菱形的4 個點的坐標(biāo),依次為(centerX,centerYwidth/2)、(centerX+width/2,centerY)、(centerX,centerY+width/2)、(centerX-width/2,centerY),用Path 對象把這4 個點連接起來并閉合,就可以繪制出菱形了。
(4)正五邊形
在繪制正五邊形時,首先固定一個中心點坐標(biāo)(centerX,center),在以width 的一半為半徑的圓上面計算出正五邊形的5 個點的坐標(biāo),依次為(centerX,centerYwidth/2)、(centerX+width/2,centerY-disY)、(centerX+disX,centerY+width/2)、(centerX-disX,centerY+width/2)、(centerX-width/2,centerY-disY),用Path 對象把這5 個點連接起來并閉合,就可以繪制出正五邊形了。
(5)正六邊形
在繪制正六邊形時,首先固定一個中心點坐標(biāo)(centerX,center),在以width 的一半為半徑的圓上面計算出正六邊形的6 個點的坐標(biāo),依次為(centerX-(width/4),centerY-width/2)、(centerX+(width/4),centerYwidth/2)、(centerX+width/2,centerY)、(centerX+(width/4),centerY+width/2)、(centerX-(width/4),centerY+width/2)、(centerX-width/2,centerY),用Path 對象把這6 個點連接起來并閉合,就可以繪制出正六邊形了。
(6)十字形狀
在繪制十字形狀時,首先固定一個中心點坐標(biāo)(centerX,center),在以width 的一半為半徑的圓上面計算出十字形狀的12 個點的坐標(biāo),依次為(centerXwidth/6,centerY-width/2)、(centerX+width/6,centerYwidth/2)、(centerX+width/6,centerY-width/6)、(centerX+width/2,centerY-width/6)、(centerX+width/2,centerY+width/6)、(centerX+width/6,centerY+width/6)、(centerX+width/6,centerY+width/2)、(centerX-width/6,centerY+width/2)、(centerX-width/6,centerY+width/6)、(centerX-width/2,centerY+width/6)、(centerXwidth/2,centerY-width/6)、(centerX-width/6,centerYwidth/6),用Path 對象把這12 個點連接起來并閉合,就可以繪制出十字形狀了。
(7)五角星形
在繪制五角星形時,首先固定一個中心點坐標(biāo)(centerX,center),在以width 的一半為半徑的圓上面計算出五角星形的5 個點的坐標(biāo),依次為(centerX,centerY-width/2)、(centerX-disX,centerY+width/2)、(centerX+width/2,centerY-disY)、(centerX-width/2,centerY-disY)、(centerX+disX,centerY+width/2),用Path對象把這5 個點連接起來并閉合,就可以繪制出五角星形了。其中,disX 和disY 的計算公式如下:
使用上面方法繪制的8 種點標(biāo)志的效果如圖2所示。
圖2 點標(biāo)志效果圖
在Android 系統(tǒng)中實現(xiàn)自定義組件,需要繼承View 類,重寫其中的一個或者多個方法,其中對on-Draw 方法的重寫尤為關(guān)鍵。本文描述的散點圖組件是有動畫效果的,在繪制過程中把背景的繪制和圖表區(qū)的繪制分開,這樣有利于控制圖表區(qū)的動畫效果。下面先對ValueAnimator 技術(shù)做簡單介紹,再對方法中的關(guān)鍵代碼做描述。
(1)ValueAnimator 類
Android 系統(tǒng)中的屬性動畫最關(guān)鍵的就是時間引擎,它負(fù)責(zé)計算各個幀的屬性值。它定義了屬性動畫的絕大部分核心功能,包括計算各幀的相關(guān)屬性值,負(fù)責(zé)處理更新事件,按屬性值的類型控制計算規(guī)則。屬性動畫主要由兩方面責(zé)成:計算各幀的相關(guān)屬性值;為指定對象設(shè)置這些計算后的值。ValueAnimator 只負(fù)責(zé)第一方面內(nèi)容,因此,要實現(xiàn)動畫必須根據(jù)ValueAnimator 計算并監(jiān)聽值更新來更新對象的相關(guān)屬性[2]。
(2)onDraw 方法的關(guān)鍵代碼
重寫onDraw 方法的關(guān)鍵代碼如下:
//根據(jù)android 系統(tǒng)屬性動畫的監(jiān)聽值animatedValue 計算將要繪制第幾個點標(biāo)志
int no=getScope(animatedValue);
//把第no 前面的所有點標(biāo)志再繪制一遍
for(int j=1;j<no;j++){
if(j<scatterPlotSeries.get(i).getSeriesValues().size()){
v=scatterPlotSeries.get(i).getSeriesValues().get(j);
//計算繪制點標(biāo)志的中心點坐標(biāo)
stopX=startLeft+(j)*avgDis;
stopY=startTop+((Float. valueOf(yItemTitle. get(yItemsCount-1))-(float)v)/(Float. valueOf(yItemTitle. get(yItemsCount-1))-Float. valueOf(yItemTitle. get(0))))*contentHeight;
//調(diào)用繪制點標(biāo)志的方法繪制點標(biāo)志
rawMark(canvas,seriesMark[i%seriesMark. length],seriesItemColor.get(i%seriesItemColor.size()),stopX,stopY,dp-Topx(markWidth));
本文實現(xiàn)的散點圖組件的效果如圖3 和圖4 所示,該散點圖可以顯示多個系列,不同的系列,不僅顏色不一樣,點標(biāo)志的樣式也不一樣,而且還具有動畫效果,動畫效果為依次從左到右顯示點標(biāo)志,相比現(xiàn)有的第三方類似的組件,具有更好的用戶體驗。在實際應(yīng)用中,該散點圖還可以自定義背景顏色、背景線條粗細(xì)、背景線條顏色、文本大小、文本顏色等屬性,滿足了Android 開發(fā)者更多的需求,顯示效果的設(shè)置多樣化,使用更加靈活。
盡管目前也有一些基于Android 的散點圖組件,或多或少都存在一些問題,如使用不便、不夠靈活等,相比之下,本文描述的散點圖組件還是具有一定的實用性和創(chuàng)新性。
本文提出的基于Android 的自定義散點圖組件可以解決一些數(shù)據(jù)展示的問題,可以展示多個系列的數(shù)據(jù),方便不同系列的數(shù)據(jù)進(jìn)行對比,經(jīng)過測試,布局整齊,響應(yīng)速度快,動畫效果良好,大大增強(qiáng)了用戶體驗,能滿足大多數(shù)Android 應(yīng)用開發(fā)人員的需求。但是,還是有一些方面需要進(jìn)一步研究,如氣泡圖、基于地圖的散點圖等,在下一步的研究工作中,將在這些方面做深入研究。
圖3 實驗效果圖一
圖4 實驗效果圖二