日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 曲线进度条,Android自定义View——使用贝塞尔曲线实现流量进度条

發布時間:2024/3/26 Android 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 曲线进度条,Android自定义View——使用贝塞尔曲线实现流量进度条 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第一次寫帶圖片的博客,多少還是有點緊張,效果不好,請將就著看,前面的圖是今天要寫的控件的效果圖,元素不多,分別是一個按鈕和一個自定義的控件。

在此以前,我看過許多的書,比如《Android群英傳》、《第一行代碼》等,也看了很多大神的博客,但是即便是這樣,當我看到這么多代碼的時候,一直都沒有真正的動手去敲過這些代碼,以至于我總是覺得自定義View是一個多么高深莫測的技術,我們這些小白是難以觸及的,但是當昨晚看了一篇雞湯之后,覺得人還是要學會專注,要耐得住寂寞,要沉得住氣。所以在未來的幾天,我也會持續的更新自己的博客,希望能夠得到大家的監督,也希望能夠一起成長。

一般來說,不到迫不得已,還是不要去自定義自己的控件,畢竟現在Android API已經給我提供了功能這么強大的控件了,而且你也能夠發現,就算是這么強大的谷歌,很多控件也還是有自己的bug,更何況我們自己寫的控件,當然了,通過自定義控件,來加深我們對Android系統的控件的了解,這也是進階的一個好方法。好了,廢話我先說到這里,下面開始今天的主題。

新建一個Class文件,命名為MyLineView,讓它繼承View,實現它的三個構造函數,緊接著初始化一些畫筆、Path,圓等數據。代碼如下:

1.定義變量

private Paint mPaint, mPaint2;

private Path mPath = new Path();

protected int mViewWidth, mViewHeight;

protected int mWidth, mHeight;

private float r, rArc, x;

private float percent = 0.5f;

private RectF rectF;

private PointF mPointF = new PointF(0, 0);

在構造函數里面初始化數據

public MyLineView(Context context, AttributeSet attrs) {

super(context, attrs);

mPaint = new Paint();

mPaint.setColor(Color.BLACK);

mPaint.setStrokeWidth(3);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setTextSize(100);

mPaint2 = new Paint();

mPaint2.setColor(Color.CYAN);

mPaint2.setStrokeWidth(8);

mPaint2.setStyle(Paint.Style.FILL);

}

準備工作已經做好了,緊接著我們復寫View的一個onSizeChanged()方法,故名思議,就是當控件的大小發生改變的時候調用。我們在這里對變量進行賦值,代碼如下:

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

/**控件的高寬*/

mViewWidth = w;

mViewHeight = h;

/**與屏幕左邊的距離和距離右邊的距離*/

mWidth = mViewWidth - getPaddingLeft() - getPaddingRight();

mHeight = mViewHeight - getPaddingTop() - getPaddingBottom();

/**定義半徑*/

r = Math.min(mWidth, mHeight) * 0.4f;

rectF = new RectF(-r, -r, r, r);

}

好了,這個時候的變量已經擁有值了,那可以開始寫最重要的操作了,開始寫onDraw();

@Override

protected void onDraw(Canvas canvas) {

// super.onDraw(canvas);

/** * 畫曲線和外圍的圓 */

canvas.translate(mViewWidth / 2, mViewHeight / 2);

canvas.drawCircle(0, 0, r, mPaint);

rArc = r * (1 - 2 * percent);

double angle = Math.acos((double) rArc / r);

x = r * (float) Math.sin(angle);

mPath.addArc(rectF, 90 - (float) Math.toDegrees(angle),

(float) Math.toDegrees(angle) * 2);

mPath.moveTo(-x, rArc);

mPath.rQuadTo(x / 2, -r / 8, x, 0);

mPath.rQuadTo(x / 2, r / 8, x, 0);

canvas.drawPath(mPath, mPaint2);

mPath.rewind();

/** * 畫文字 */

NumberFormat numberFormat = NumberFormat.getPercentInstance();

numberFormat.setMinimumFractionDigits(1);

textCenter(new String[] { numberFormat.format(percent) }, mPaint,

canvas, mPointF, Paint.Align.CENTER);

}

文字的處理:

/** * 多行文本居中、居右、居左 * *@param strings * 文本字符串列表 *@param paint * 畫筆 *@param canvas * 畫布 *@param point * 點的坐標 *@param align * 居中、居右、居左 */

protected void textCenter(String[] strings, Paint paint, Canvas canvas,

PointF point, Paint.Align align) {

paint.setTextAlign(align);

Paint.FontMetrics fontMetrics = paint.getFontMetrics();

float top = fontMetrics.top;

float bottom = fontMetrics.bottom;

int length = strings.length;

float total = (length - 1) * (-top + bottom)

+ (-fontMetrics.ascent + fontMetrics.descent);

float offset = total / 2 - bottom;

for (int i = 0; i < length; i++) {

float yAxis = -(length - i - 1) * (-top + bottom) + offset;

canvas.drawText(strings[i], point.x, point.y + yAxis, paint);

}

}

好了,截止目前已經把控件寫好了,但是作為一個控件,數據不可能固定不變,所以向外暴露一個方法,用于改變進度的大小;

public void setProgress(float percent) {

if (percent != 0) {

this.percent = percent;

} else {

this.percent = 0;

}

/**重繪*/

invalidate();

}

好了全部流程都在這里了,最后再貼上全部的代碼;

package com.example.view.weight;

import java.text.NumberFormat;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Path;

import android.graphics.PointF;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.View;

/** * 貝塞爾曲線 * *@author cheng * */

public class MyLineView extends View {

private Paint mPaint, mPaint2;

private Path mPath = new Path();

protected int mViewWidth, mViewHeight;

protected int mWidth, mHeight;

private float r, rArc, x;

private float percent = 0.5f;

private RectF rectF;

private PointF mPointF = new PointF(0, 0);

public MyLineView(Context context) {

this(context, null);

}

public MyLineView(Context context, AttributeSet attrs) {

super(context, attrs);

mPaint = new Paint();

mPaint.setColor(Color.BLACK);

mPaint.setStrokeWidth(3);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setTextSize(100);

mPaint2 = new Paint();

mPaint2.setColor(Color.CYAN);

mPaint2.setStrokeWidth(8);

mPaint2.setStyle(Paint.Style.FILL);

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mViewWidth = w;

mViewHeight = h;

mWidth = mViewWidth - getPaddingLeft() - getPaddingRight();

mHeight = mViewHeight - getPaddingTop() - getPaddingBottom();

r = Math.min(mWidth, mHeight) * 0.4f;

rectF = new RectF(-r, -r, r, r);

}

@Override

protected void onDraw(Canvas canvas) {

// super.onDraw(canvas);

/** * 畫曲線和外圍的圓 */

canvas.translate(mViewWidth / 2, mViewHeight / 2);

canvas.drawCircle(0, 0, r, mPaint);

rArc = r * (1 - 2 * percent);

double angle = Math.acos((double) rArc / r);

x = r * (float) Math.sin(angle);

mPath.addArc(rectF, 90 - (float) Math.toDegrees(angle),

(float) Math.toDegrees(angle) * 2);

mPath.moveTo(-x, rArc);

mPath.rQuadTo(x / 2, -r / 8, x, 0);

mPath.rQuadTo(x / 2, r / 8, x, 0);

canvas.drawPath(mPath, mPaint2);

mPath.rewind();

/** * 畫文字 */

NumberFormat numberFormat = NumberFormat.getPercentInstance();

numberFormat.setMinimumFractionDigits(1);

textCenter(new String[] { numberFormat.format(percent) }, mPaint,

canvas, mPointF, Paint.Align.CENTER);

}

/** * 多行文本居中、居右、居左 * *@param strings * 文本字符串列表 *@param paint * 畫筆 *@param canvas * 畫布 *@param point * 點的坐標 *@param align * 居中、居右、居左 */

protected void textCenter(String[] strings, Paint paint, Canvas canvas,

PointF point, Paint.Align align) {

paint.setTextAlign(align);

Paint.FontMetrics fontMetrics = paint.getFontMetrics();

float top = fontMetrics.top;

float bottom = fontMetrics.bottom;

int length = strings.length;

float total = (length - 1) * (-top + bottom)

+ (-fontMetrics.ascent + fontMetrics.descent);

float offset = total / 2 - bottom;

for (int i = 0; i < length; i++) {

float yAxis = -(length - i - 1) * (-top + bottom) + offset;

canvas.drawText(strings[i], point.x, point.y + yAxis, paint);

}

}

public void setProgress(float percent) {

if (percent != 0) {

this.percent = percent;

} else {

this.percent = 0;

}

invalidate();

}

}

布局里面的代碼:

android:id="@+id/view_line"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:gravity="center" />

總結

以上是生活随笔為你收集整理的android 曲线进度条,Android自定义View——使用贝塞尔曲线实现流量进度条的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。