弧線展示圖
如下圖所示就是這次的弧線展示圖:
根據書中的代碼增加了可自定義弧形的大小,並且可以在佈局中自定義各部分的顏色和大小設置。
接下來開始介紹如何創建一個這樣的自定義View。
很明顯,這個自定義View其實分爲三個部分,分別是中間的圓形、中間顯示的文字和外圈的弧線。有了這樣的思路,只要在onDraw()方法中一個個去繪製就可以了。
首先,在初始化的時候,設置好繪製三種圖形的參數。圓的代碼如下所示:
// 中心圓的圓心座標
mCircleXY = length/2;
// 中心圓的半徑
mRadius = (float) (length*0.5/2);
繪製弧線,需要指定其橢圓的外接矩形,代碼如下所示:
// 繪製弧形的外接矩形屬性
mArcRectF = new RectF(
(float) (length * 0.1),
(float) (length * 0.1),
(float) (length * 0.9),
(float) (length * 0.9)
);
繪製文字,只要設置好文字的起始繪製位置就可以了。
接下來,我們就可以在onDraw()方法中進行繪製了,代碼如下所示:
// 繪製中心圓
canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
// 繪製弧形
canvas.drawArc(mArcRectF, 270, mSweepValue, false, mArcPaint);
// 繪製文字
// 測量字體寬度,根據字體的寬度設置在圓環中間
float textWidth = mTextPaint.measureText(mShowText);
// 通過文字的大小和長度將文字繪製在圓的正中心
canvas.drawText(mShowText, 0,mShowText.length(), mCircleXY-(textWidth/2), mCircleXY+(mShowTextSize/4), mTextPaint);
當然,如果想在佈局時給這個簡單的View自定義屬性的話,可以通過attrs.xml文件給這個控件添加可以自定義的屬性,attrs.xml中設置的屬性可以根據需要添加,在java中的調用方法如下所示:
// 將所有的attrs中的所有樣式都存儲到TypeArray中
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.ArcDisplay);
// 給中心圓設置屬性
mCirclePaint = new Paint();
mCirclePaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerCircleColor,
ContextCompat.getColor(context,R.color.defCircleColor)));
// 給弧形設置屬性
mArcPaint = new Paint();
mArcPaint.setColor(ta.getColor(R.styleable.ArcDisplay_arcColor,
ContextCompat.getColor(context,R.color.defArcColor)));
mArcPaint.setStrokeWidth(ta.getInteger(R.styleable.ArcDisplay_arcWidth, 60));
mArcPaint.setStyle(Paint.Style.STROKE);
setProgress(ta.getFloat(R.styleable.ArcDisplay_arcAngle, 10));
// 給中間文字設置屬性
mTextPaint = new Paint();
mTextPaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerTextColor,
ContextCompat.getColor(context,R.color.defTextColor)));
mShowTextSize = ta.getInteger(R.styleable.ArcDisplay_centerFontSize, 10);
mTextPaint.setTextSize(mShowTextSize);
ta.recycle();
當調用者不具體指定屬性時,可以給它們都設置一個默認值。
設置完自定義屬性後,開始設置如何通過百分比的形式讓弧形顯示準確的比例長度,代碼如下所示:
/**
* 給弧形設置一個角度(百分比的形式)
* @param mSweepValue 角度比例
*/
public void setProgress(float mSweepValue){
if (mSweepValue != 0) {
this.mSweepValue = (float) (360.0 * (mSweepValue / 100.0));
mShowText = mSweepValue + "%";
} else {
this.mSweepValue = 25;
mShowText = 25 + "%";
}
invalidate();
}
通過以上方法就可以實現輸入具體的百分比讓弧形長度準確顯示。
以上就是弧形展示圖的實現步驟,有沒有很簡單。
代碼
以下是完整代碼:
package com.example.customarc;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import com.example.arcdisplay.R;
/**
* 自定義弧線展示圖
* Created by shize on 2016/8/30.
*/
public class ArcDisplay extends View {
// 中心圓的xy軸座標
private float mCircleXY;
// 中心圓的半徑
private float mRadius;
// 中心圓的畫筆
private Paint mCirclePaint;
// 弧線橢圓的畫筆
private Paint mArcPaint;
// 弧線掃過的角度
private float mSweepValue;
// 中心圓的文字
private String mShowText;
// 文字的畫筆
private Paint mTextPaint;
// 畫布的寬
private int length;
// 文字大小尺寸
private int mShowTextSize;
public ArcDisplay(Context context) {
super(context);
}
public ArcDisplay(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context, attrs);
}
public ArcDisplay(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context, attrs);
}
public void initView(Context context, AttributeSet attrs){
// 將所有的attrs中的所有樣式都存儲到TypeArray中
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.ArcDisplay);
// 給中心圓設置屬性
mCirclePaint = new Paint();
mCirclePaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerCircleColor,
ContextCompat.getColor(context,R.color.defCircleColor)));
// 給弧形設置屬性
mArcPaint = new Paint();
mArcPaint.setColor(ta.getColor(R.styleable.ArcDisplay_arcColor,
ContextCompat.getColor(context,R.color.defArcColor)));
mArcPaint.setStrokeWidth(ta.getInteger(R.styleable.ArcDisplay_arcWidth, 60));
mArcPaint.setStyle(Paint.Style.STROKE);
setProgress(ta.getFloat(R.styleable.ArcDisplay_arcAngle, 10));
// 給中間文字設置屬性
mTextPaint = new Paint();
mTextPaint.setColor(ta.getColor(R.styleable.ArcDisplay_centerTextColor,
ContextCompat.getColor(context,R.color.defTextColor)));
mShowTextSize = ta.getInteger(R.styleable.ArcDisplay_centerFontSize, 10);
mTextPaint.setTextSize(mShowTextSize);
ta.recycle();
}
@Override
protected void onSizeChanged(int w,int h,int oldW,int oldH){
super.onSizeChanged(w,h,oldW,oldH);
length = w;
mCircleXY = length/2;
mRadius = (float) (length*0.5/2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 弧線橢圓的外接矩形
RectF mArcRectF;
// 繪製弧形的外接矩形屬性
mArcRectF = new RectF(
(float) (length * 0.1),
(float) (length * 0.1),
(float) (length * 0.9),
(float) (length * 0.9)
);
// 繪製中心圓
canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
// 繪製弧形
canvas.drawArc(mArcRectF, 270, mSweepValue, false, mArcPaint);
// 繪製文字
// 測量字體寬度,根據字體的寬度設置在圓環中間
float textWidth = mTextPaint.measureText(mShowText);
// 通過文字的大小和長度將文字繪製在圓的正中心
canvas.drawText(mShowText, 0,mShowText.length(), mCircleXY-(textWidth/2), mCircleXY+(mShowTextSize/4), mTextPaint);
}
/**
* 給弧形設置一個角度(百分比的形式)
* @param mSweepValue 角度比例
*/
public void setProgress(float mSweepValue){
if (mSweepValue != 0) {
this.mSweepValue = (float) (360.0 * (mSweepValue / 100.0));
mShowText = mSweepValue + "%";
} else {
this.mSweepValue = 25;
mShowText = 25 + "%";
}
invalidate();
}
}
佈局文件調用代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.arcdisplay.MainActivity">
<com.example.customarc.ArcDisplay
android:id="@+id/arc"
android:layout_width="match_parent"
android:layout_height="400dp"
custom:arcAngle="60"
custom:arcColor="#00ff00"
custom:arcWidth="60"
custom:centerCircleColor="#00ff00"
custom:centerFontSize="70"
custom:centerTextColor="#f33" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/txt_angle"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/angle"
android:inputType="numberDecimal"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnYes"
android:text="@string/btn_txt_yes"/>
</LinearLayout>
以下是attrs.xml的代碼:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ArcDisplay">
<attr name="centerFontSize" format="integer" />
<attr name="centerTextColor" format="color" />
<attr name="centerCircleColor" format="color" />
<attr name="arcColor" format="color" />
<attr name="arcAngle" format="float" />
<attr name="arcWidth" format="integer" />
</declare-styleable>
</resources>
感謝閱讀,下次再見。