亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Android開(kāi)發(fā)自定義控件之折線(xiàn)圖實(shí)現(xiàn)方法詳解

瀏覽:3日期:2022-09-24 09:49:53

本文實(shí)例講述了Android開(kāi)發(fā)自定義控件之折線(xiàn)圖實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:

前言

折線(xiàn)圖是Android開(kāi)發(fā)中經(jīng)常會(huì)碰到的效果,但由于涉及自定義View的知識(shí),對(duì)許多剛?cè)腴T(mén)的小白來(lái)說(shuō)會(huì)覺(jué)得很高深。其實(shí)不然,接下來(lái)我就以盡量通俗的語(yǔ)言來(lái)說(shuō)明下圖折線(xiàn)圖效果的實(shí)現(xiàn)過(guò)程。

效果圖

Android開(kāi)發(fā)自定義控件之折線(xiàn)圖實(shí)現(xiàn)方法詳解

實(shí)現(xiàn)過(guò)程

首先,選擇自定義控件的方式。

自定義控件的實(shí)現(xiàn)有四種方式:

1.繼承View,重寫(xiě)onDraw、onMeasure等方法。2.繼承已有的View(比如TextView)。3.繼承ViewGroup實(shí)現(xiàn)自定義布局。4.繼承已有的ViewGroup(比如LinearLayout)。

由于我們不需要多個(gè)控件進(jìn)行組合,也不需要在原有控件基礎(chǔ)上改造,故我們采用第1種方式即繼承View來(lái)實(shí)現(xiàn)。代碼如下,新建一個(gè)ChartView類(lèi)繼承自View,并實(shí)現(xiàn)他的幾個(gè)構(gòu)造方法,并重寫(xiě)onDraw和onMeasure方法,因?yàn)槲覀円趏nDraw方法里面進(jìn)行繪制工作,并且我希望這個(gè)控件的長(zhǎng)寬是相等的,所以在onMeasure方法設(shè)置寬高相等。設(shè)置長(zhǎng)寬相等的方式很簡(jiǎn)單,我們不需要自己去測(cè)量實(shí)現(xiàn),只需要調(diào)用父類(lèi)的onMeasure方法,傳參數(shù)(寬高值)時(shí)將都傳入寬度(或者高度)即可。

public class ChartView extends View { public ChartView(Context context) { super(context); } public ChartView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public ChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); }}

其次,繪制簡(jiǎn)單圖形并顯示出來(lái)。

在進(jìn)行繪制之前,我們要進(jìn)行若干初始化工作,其中就包括畫(huà)筆的初始化。然后就可以進(jìn)行繪制了,我們先繪制一個(gè)簡(jiǎn)單的圓圈,然后將控件放到布局文件中,運(yùn)行看看效果。

ChartView代碼

public class ChartView extends View { // 畫(huà)筆 private Paint paint; /** * 構(gòu)造函數(shù) */ public ChartView(Context context) { super(context); initWork(); } /** * 構(gòu)造函數(shù) */ public ChartView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initWork(); } /** * 構(gòu)造函數(shù) */ public ChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initWork(); } /** * 初始化工作 */ private void initWork() { initPaint(); } /** * 畫(huà)筆設(shè)置 */ private void initPaint() { paint = new Paint(Paint.ANTI_ALIAS_FLAG); // 畫(huà)筆樣式為填充 paint.setStyle(Paint.Style.FILL); // 顏色設(shè)為紅色 paint.setColor(Color.RED); // 寬度為3像素 paint.setStrokeWidth(3); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 畫(huà)圓 canvas.drawCircle(300,300,100,paint); }}

activity_main.xml

<?xml version='1.0' encoding='utf-8'?><android.support.constraint.ConstraintLayout xmlns:android='http://schemas.android.com/apk/res/android' android:layout_width='match_parent' android:layout_height='match_parent' <com.toprs.linechart.ChartView android:layout_width='match_parent' android:layout_height='match_parent'/></android.support.constraint.ConstraintLayout>

效果:

Android開(kāi)發(fā)自定義控件之折線(xiàn)圖實(shí)現(xiàn)方法詳解

然后,繪制圖表。

到目前為止,已經(jīng)實(shí)現(xiàn)了最簡(jiǎn)單的一個(gè)自定義控件,雖然它什么功能都沒(méi)有,只是簡(jiǎn)單顯示一個(gè)紅色圓圈,但本質(zhì)都是一樣的。接下來(lái)就開(kāi)始圖表的繪制。

1.初始化一些需要使用的值。

// 刻度之間的距離 private int degreeSpace;

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 控件上下左右邊界四至及控件的寬度(同時(shí)也是高度!) int left = getLeft(); int right = getRight(); int top = getTop(); int bottom = getBottom(); int w = getWidth(); // 圖表距離控件邊緣的距離 int graphPadding = w / 10; // 圖表上下左右四至 int graphLeft = left + graphPadding; int graphBottom = bottom - graphPadding; int graphRight = right - graphPadding; int graphTop = top + graphPadding; // 圖表寬度(也等同高度奧~) int graphW = graphRight - graphLeft; // 刻度之間的距離 degreeSpace = graphW / 8; }

2.灰色背景

// 背景 canvas.drawColor(Color.LTGRAY);

3.坐標(biāo)系

// 畫(huà)筆設(shè)置樣式為STROKE樣式,即只劃線(xiàn)不填充 paint.setStyle(Paint.Style.STROKE); // 坐標(biāo)系繪制 Path pivotPath = new Path(); //Y軸 pivotPath.moveTo(graphLeft, graphBottom); pivotPath.lineTo(graphLeft, graphTop); //Y軸箭頭 pivotPath.lineTo(graphLeft - 12, graphTop + 20); pivotPath.moveTo(graphLeft, graphTop); pivotPath.lineTo(graphLeft + 12, graphTop + 20); //X軸 pivotPath.moveTo(graphLeft, graphBottom); pivotPath.lineTo(graphRight, graphBottom); //X軸箭頭 pivotPath.lineTo(graphRight - 20, graphBottom + 12); pivotPath.moveTo(graphRight, graphBottom); pivotPath.lineTo(graphRight - 20, graphBottom - 12); canvas.drawPath(pivotPath, paint);

4.刻度虛線(xiàn)及數(shù)字

// Y軸刻度虛線(xiàn) for (int i = 1; i < 8; i++) { Path yKeduPath = new Path(); // 線(xiàn) paint.setColor(Color.WHITE); paint.setStrokeWidth(1); paint.setStyle(Paint.Style.STROKE); paint.setPathEffect(new DashPathEffect(new float[]{5,5},0)); yKeduPath.moveTo(graphLeft, graphBottom - i * degreeSpace); yKeduPath.lineTo(graphRight, graphBottom - i * degreeSpace); canvas.drawPath(yKeduPath, paint); // 數(shù)字 paint.setColor(Color.BLACK); paint.setStyle(Paint.Style.FILL); paint.setTextSize(25); paint.setPathEffect(null); canvas.drawText(i + '', graphPadding / 2, graphBottom - i * degreeSpace, paint); } // X軸刻度虛線(xiàn) for (int i = 1; i < 8; i++) { Path xKeduPath = new Path(); // 線(xiàn) paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(1); paint.setPathEffect(new DashPathEffect(new float[]{5,5},0)); xKeduPath.moveTo(graphLeft + i * degreeSpace, graphBottom); xKeduPath.lineTo(graphLeft + i * degreeSpace, graphTop); canvas.drawPath(xKeduPath, paint); // 數(shù)字 paint.setColor(Color.BLACK); paint.setStyle(Paint.Style.FILL); paint.setTextSize(25); paint.setPathEffect(null); canvas.drawText(i + '', graphLeft + i * degreeSpace, graphBottom + graphPadding / 2, paint); }

5.折線(xiàn)

在繪制折線(xiàn)之前,我們先要初始化幾個(gè)參數(shù)。

// 模擬數(shù)據(jù) private float[] data = {3.2f, 4.3f, 2.5f, 3.2f, 3.8f, 7.1f, 1.3f, 5.6f}; // 當(dāng)前顯示的數(shù)據(jù)數(shù)量 private int showNum=1;

// 折線(xiàn) Path linePath = new Path(); for (int i = 0; i < showNum; i++) { int toPointX = graphLeft + i * degreeSpace; int toPointY = graphBottom - ((int) (data[i] * degreeSpace)); paint.setColor(Color.YELLOW); paint.setStyle(Paint.Style.STROKE); if (i==0){ linePath.moveTo(toPointX,toPointY); }else { linePath.lineTo(toPointX, toPointY); } // 節(jié)點(diǎn)圓圈 canvas.drawCircle(toPointX, toPointY,10,paint); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(toPointX,toPointY,7,paint); } paint.setColor(Color.YELLOW); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(3); canvas.drawPath(linePath, paint);

6.讓圖表動(dòng)起來(lái)

為了實(shí)現(xiàn)數(shù)據(jù)依次顯現(xiàn)的動(dòng)畫(huà),我們開(kāi)啟一個(gè)線(xiàn)程是當(dāng)前顯示的數(shù)據(jù)數(shù)量即showNum變量不斷加一,并間隔時(shí)間0.5秒。然后postInvalidate()重繪即可。

private void initWork() { initPaint(); // 開(kāi)啟線(xiàn)程,沒(méi)隔0.5秒showNum加一 new Thread(new Runnable() { @Override public void run() {while (true){ if (showNum<data.length){ showNum++; }else { showNum=1; } // 重繪 postInvalidate(); // 休眠0.5秒 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }} } }).start(); }

好了,運(yùn)行一下,便會(huì)實(shí)現(xiàn)上面的效果了。如果你覺(jué)得效果不夠炫酷或者功能太少,那就自己完善吧~~

結(jié)語(yǔ)

由于自定義控件是Android進(jìn)階路上必然要碰到的知識(shí),所以希望大家重視。其實(shí)自定義控件說(shuō)難也難說(shuō)簡(jiǎn)單也簡(jiǎn)單。實(shí)現(xiàn)一些普通的效果還是很方便的,像這次舉的例子,但如果要實(shí)現(xiàn)各種炫酷效果并且要完善各種功能的話(huà),就需要各種知識(shí)的配合了,包括數(shù)學(xué)、物理、繪圖等知識(shí)。所以還是需要平時(shí)不斷積累的,看到別人的控件很棒的時(shí)候自己可以試著去實(shí)現(xiàn)一下,對(duì)自己的知識(shí)庫(kù)不斷進(jìn)行補(bǔ)充,自然會(huì)嫻熟的運(yùn)用。本人也是菜鳥(niǎo)一枚,望共勉!!

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Android控件用法總結(jié)》、《Android開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android視圖View技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android數(shù)據(jù)庫(kù)操作技巧總結(jié)》及《Android資源操作技巧匯總》

希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。

標(biāo)簽: Android
相關(guān)文章:
主站蜘蛛池模板: 18成人网 | 久久这里只有精品首页 | 国产麻豆传媒视频 | 日韩v片| 日本黄色免费网址 | 一级特黄特交牲大片 | 日韩三区 | 日韩在线www| 国产在线一二三区 | 国产精彩视频在线观看免费蜜芽 | 久久99青青久久99久久 | 五月天在线婷婷 | 黄色日韩 | 亚洲尹人香蕉网在线视颅 | 中文字幕不卡一区 二区三区 | 成人日b视频 | 五月六月伊人狠狠丁香网 | 免费又黄又硬又大爽日本 | 国产欧美日韩精品一区二 | 国产成人激烈叫床视频 | 国产福利在线观看永久免费 | 一级做a爱过程免费视频日本 | 伊人激情 | 伊人久热这里只有精品视频99 | 成人看片又黄又爽 | 国产三级精品三级在线观看 | 美国一级大黄一片免费网站 | 精品视频h | 国产精品杨幂va在线观看 | 在线日韩麻豆一区 | 欧美人与善交大片 | 免费国产好深啊好涨好硬视频 | 国产成人精品午夜视频' | 国产免费人做爰午夜视频 | 九九热国产精品视频 | 在线观看91精品国产hd | 成人三级做爰在线观看男女 | 麻豆国产精品视频 | 草久影院 | 国产成人自产拍免费视频 | 日本人与黑人xxxx |