自定義view實現半圓環
1.自定義屬性
<declare-styleable name="SemicircleView">
<attr name="radius" format="dimension" />
<attr name="strokeWidth" format="dimension" />
<attr name="bgArcColor" format="color" />
<attr name="usedArcColor" format="color" />
<attr name="usedTextSize" format="dimension" />
<attr name="usedPercentTextSize" format="dimension" />
<attr name="percentTextSize" format="dimension" />
</declare-styleable>
2.自定義View
package com.anhuitelecom.share.activity.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import com.anhuitelecom.share.activity.R;
/**
*
* @ClassName: SemicircleView
* @Description: 自定義view 實現半圓弧
* @author chenzheng
* @date 2017-2-21 下午2:44:16
*/
public class SemicircleView extends View{
//線圓弧畫筆
private Paint mLineArcPaint;
//背景圓弧畫筆
private Paint mBackgroudArcPaint;
//已使用圓弧畫筆
private Paint mUsedArcPaint;
//已使用以及流量文字畫筆
private Paint mUsedTxtPaint;
//已使用百分比文字畫筆
private Paint mUsedPercentTxtPaint;
//百分號畫筆
private Paint mPercentTxtPaint;
//最外層圓弧線顏色
private int mLineArcColor;
//背景圓環顏色
private int mBackgroundArcColor;
//已使用圓弧顏色
private int mUsedArcColor;
//圓弧半徑
private float mArcRadius;
//外線大半徑
private float mLineRadius;
//圓弧寬度
private float mArcStrokeWidth;
// 圓心x座標
private int mXCenter;
// 圓心y座標
private int mYCenter;
//已使用百分比
private float mProgress=0;
//動畫展示弧度
private float mShowProgress;
private Context mContext;
//已使用和總流量
private String mUserdAndAll;
private float mUsedTextSize;
private float mUsedPercentTextSize;
private float mPercentTextSize;
private float mUsedPercentTxtHeight;
//private CircleThread
private Handler circleHandler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == 1){
float temp = (Float)msg.obj;
setShowProgress(temp);
}
};
};
public SemicircleView(Context context) {
this(context, null);
}
public SemicircleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SemicircleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
// 獲取自定義的屬性
initAttrs(context, attrs);
initVariable();
}
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.SemicircleView, 0, 0);
mLineRadius = typeArray.getDimension(R.styleable.SemicircleView_radius, 120);
mArcStrokeWidth = typeArray.getDimension(R.styleable.SemicircleView_strokeWidth, 12);
mBackgroundArcColor = typeArray.getColor(R.styleable.SemicircleView_bgArcColor, 0xFFFFFFFF);
mUsedArcColor = typeArray.getColor(R.styleable.SemicircleView_usedArcColor, 0xFFFF3D3B);
mUsedTextSize = typeArray.getDimension(R.styleable.SemicircleView_usedTextSize, 14);
mUsedPercentTextSize = typeArray.getDimension(R.styleable.SemicircleView_usedPercentTextSize, 52);
mPercentTextSize = typeArray.getDimension(R.styleable.SemicircleView_percentTextSize, 16);
typeArray.recycle();
}
private void initVariable() {
//初始化一些值
mLineRadius = mLineRadius + mArcStrokeWidth / 2;
mArcRadius = mLineRadius-1.8f*mArcStrokeWidth;
mLineArcColor = 0x33FFFFFF;
mUserdAndAll = "0M/0M";
//外層線圓弧畫筆設定
mLineArcPaint = new Paint();
mLineArcPaint.setAntiAlias(true);
mLineArcPaint.setColor(mLineArcColor);
mLineArcPaint.setStyle(Paint.Style.STROKE);
mLineArcPaint.setStrokeWidth(1);
mLineArcPaint.setStrokeCap(Paint.Cap.ROUND);//開啟顯示邊緣為圓形
//背景圓弧畫筆設定
mBackgroudArcPaint = new Paint();
mBackgroudArcPaint.setAntiAlias(true);
mBackgroudArcPaint.setColor(mBackgroundArcColor);
mBackgroudArcPaint.setStyle(Paint.Style.STROKE);
mBackgroudArcPaint.setStrokeWidth(mArcStrokeWidth);
mBackgroudArcPaint.setStrokeCap(Paint.Cap.ROUND);//開啟顯示邊緣為圓形
//已使用多少圓環畫筆設定
mUsedArcPaint = new Paint();
mUsedArcPaint.setAntiAlias(true);
mUsedArcPaint.setColor(mUsedArcColor);
mUsedArcPaint.setStyle(Paint.Style.STROKE);
mUsedArcPaint.setStrokeWidth(mArcStrokeWidth);
mUsedArcPaint.setStrokeCap(Paint.Cap.ROUND);//開啟顯示邊緣為圓形
mUsedTxtPaint = new Paint();
mUsedTxtPaint.setAntiAlias(true);
mUsedTxtPaint.setStyle(Paint.Style.FILL);
mUsedTxtPaint.setColor(0x80FFFFFF);
mUsedTxtPaint.setTextSize(mUsedTextSize);
//百分比數字畫筆
mUsedPercentTxtPaint = new Paint();
mUsedPercentTxtPaint.setAntiAlias(true);
mUsedPercentTxtPaint.setStyle(Paint.Style.FILL);
mUsedPercentTxtPaint.setColor(0xFFFFFFFF);
mUsedPercentTxtPaint.setTextSize(mUsedPercentTextSize);
//百分號畫筆
mPercentTxtPaint = new Paint();
mPercentTxtPaint.setAntiAlias(true);
mPercentTxtPaint.setStyle(Paint.Style.FILL);
mPercentTxtPaint.setColor(0xFFFFFFFF);
mPercentTxtPaint.setTextSize(mPercentTextSize);
//獲取字型高度
FontMetrics fm = mUsedPercentTxtPaint.getFontMetrics();
mUsedPercentTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
mXCenter = getWidth() / 2;
mYCenter = getHeight() / 2;
RectF lineOval = new RectF();
lineOval.left = (mXCenter - mLineRadius);
lineOval.top = (mYCenter - mLineRadius);
lineOval.right = mLineRadius * 2 + (mXCenter - mLineRadius);
lineOval.bottom = mLineRadius * 2 + (mYCenter - mLineRadius);
RectF oval = new RectF();
oval.left = (mXCenter - mArcRadius);
oval.top = (mYCenter - mArcRadius);
oval.right = mArcRadius * 2 + (mXCenter - mArcRadius);
oval.bottom = mArcRadius * 2 + (mYCenter - mArcRadius);
//繪製最外面圓弧線
canvas.drawArc(lineOval, -225, 270, false, mLineArcPaint);
//繪製背景圓弧
canvas.drawArc(oval, -225, 270, false, mBackgroudArcPaint);
//繪製已使用圓弧
float mShowDegree = mShowProgress/100*270;
canvas.drawArc(oval, -225, mShowDegree, false, mUsedArcPaint);
//已使用文字
Rect usedRect = new Rect();
String usedStr = "已使用";
mUsedTxtPaint.getTextBounds(usedStr, 0, usedStr.length(), usedRect);
int usedX = mXCenter - usedRect.width() / 2;
canvas.drawText(usedStr, usedX, mYCenter-mArcRadius*0.6f, mUsedTxtPaint);
//已使用和總流量
Rect ua_rect = new Rect();
mUsedTxtPaint.getTextBounds(mUserdAndAll, 0, mUserdAndAll.length(), ua_rect);
int uaX = mXCenter - ua_rect.width() / 2;
canvas.drawText(mUserdAndAll, uaX, mYCenter+mArcRadius*0.6f, mUsedTxtPaint);
//百分比數字
String progressStr = (int)mShowProgress+"";
String percentStr = "%";
float usedPercentWidth = mUsedPercentTxtPaint.measureText(progressStr, 0, progressStr.length());
float percentWidth = mPercentTxtPaint.measureText(percentStr, 0, percentStr.length());
float upX = mXCenter-(usedPercentWidth + percentWidth)/2;
canvas.drawText(progressStr, upX, mYCenter+mUsedPercentTxtHeight/3, mUsedPercentTxtPaint);
float pX = upX + usedPercentWidth;
canvas.drawText(percentStr, pX, mYCenter+mUsedPercentTxtHeight/3, mPercentTxtPaint);
}
private void setShowProgress(float progress){
this.mShowProgress = progress;
postInvalidate();
}
public void setProgress(float progress) {
mProgress = progress;
new Thread(new CircleThread()).start();
}
public void setUsedArcColor(int usedArcColor) {
this.mUsedArcColor = usedArcColor;
if(mUsedArcPaint!=null){
mUsedArcPaint.setColor(mUsedArcColor);
}
}
public void setUsedAndAll(String usedAndAll) {
this.mUserdAndAll = usedAndAll;
}
public static int dp2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
private class CircleThread implements Runnable{
int m=0;
float i=0;
@Override
public void run() {
// TODO Auto-generated method stub
while(!Thread.currentThread().isInterrupted()){
try {
Thread.sleep(30);
m++;
Message msg = new Message();
msg.what = 1;
if(i < mProgress){
i += m;
msg.obj = i;
circleHandler.sendMessage(msg);
}else{
i = mProgress;
msg.obj = i;
circleHandler.sendMessage(msg);
return;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
3.外部呼叫
<com.view.SemicircleView
android:id="@+id/semicircleView"
android:layout_width="215dp"
android:layout_height="215dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
halfArc:bgArcColor="#ffffff"
halfArc:percentTextSize="16sp"
halfArc:radius="100dp"
halfArc:strokeWidth="11dp"
halfArc:usedArcColor="#FF3D3B"
halfArc:usedPercentTextSize="52sp"
halfArc:usedTextSize="14sp" />
semicircleView.setUsedAndAll("170M/200M");
semicircleView.setProgress(81);
4.實現效果圖
相關文章
- 自定義圓環
- Flutter自定義View的實現FlutterView
- Android自定義View之圖片外形特效——輕鬆實現圓角和圓形圖片AndroidView特效
- 【朝花夕拾】Android自定義View篇之(四)自定義View的三種實現方式及自定義屬性詳解AndroidView
- ios自定義圓環進度條iOS
- 自定義VIEWView
- Android自定義view之實現帶checkbox的SnackbarAndroidView
- Android自定義View:快遞時間軸實現AndroidView
- Android 自定義 View 實現橫行時間軸AndroidView
- flutter-簡單實現找妹子自定義viewFlutterView
- 分享一個Kotlin 寫的超級 簡單的自定義View,圓環統計KotlinView
- 自定義View實用小技巧View
- Android自定義View:View(二)AndroidView
- Android 自定義 View 實戰之 PuzzleViewAndroidView
- 『自定義View實戰』—— 仿ios圖示下載viewViewiOS
- 自定義View事件之進階篇(四)-自定義Behavior實戰View事件
- 自定義View事件篇進階篇(二)-自定義NestedScrolling實戰View事件
- 簡單介紹Android自定義View實現時鐘功能AndroidView
- Android自定義View整合AndroidView
- 自定義View之SwitchViewView
- Android自定義view-自繪ViewAndroidView
- android自定義view(自定義數字鍵盤)AndroidView
- 直播系統程式碼,Android自定義View實現呼吸燈效果AndroidView
- 直播平臺搭建,自定義View實現loading動畫載入View動畫
- 直播平臺原始碼,Android自定義View實現呼吸燈效果原始碼AndroidView
- Android技術分享|【自定義View】實現Material Design的Loading效果AndroidViewMaterial Design
- Android自定義View實現流式佈局(熱門標籤效果)AndroidView
- 淺談Kotlin實戰篇之自定義View圖片圓角簡單應用(一)KotlinView
- 封裝自定義圓角方向並且可設定投影的View封裝View
- 自定義view————Banner輪播View
- Flutter 自定義繪製 ViewFlutterView
- Flutter自定義View(二)—— MultiChildRenderObejctWidgetFlutterView
- 重拾Android自定義ViewAndroidView
- Android自定義View:ViewGroup(三)AndroidView
- Android 自定義 View 之 LeavesLoadingAndroidView
- Android 自定義View:深入理解自定義屬性(七)AndroidView
- 自定義圓環,跟隨手指旋轉角度加減layer
- Android自定義View——從零開始實現書籍翻頁效果(二)AndroidView
- Android自定義View之分貝儀AndroidView