歡迎來我的個人部落格檢視更多文章: Cy的個人部落格
不久之前寫過一篇基礎的自定義View的博文,今天就來實踐一下自定義View,參考了網上一個自定義View控制元件的博文完成的(畢竟還是小白)。以下是我完成的一些步驟:
- 首先肯定需要編寫一個類,讓它繼承自View(感覺我這個簡單的自定義view繼承RelativeLayout就夠了),然後重寫構造方法咯,這個簡單,程式碼如下(一般大家都重寫三個構造方法,雖然不太理解,但是對於我這個簡單的自定義View是重寫兩個構造方法是能實現的):
public class QuanView extends RelativeLayout{
public QuanView(Context context) {
super(context);
}
public QuanView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
複製程式碼
- 然後就是初始化畫筆,然後設定一些屬性咯,所以現在的程式碼如下:
public class QuanView extends RelativeLayout{
private Paint mPaint;
private float mGap=20; //圓和圓之間的間距
private float mRadius=15; //圓的半徑
private float mRemain; //畫完圓和圓間距後多出來的距離
private int mCircleNum; //圓圈的數量
public QuanView(Context context) {
super(context);
initPaint();
}
public QuanView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
private void initPaint(){
mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.WHITE);
}
}
複製程式碼
- 在上一篇自定義博文中我們知道onSizeChanged方法會在onDraw方法前執行,我們可以在這個方法中計算好需要繪製的圓圈的個數,所以onSizeChanged方法中程式碼如下:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mRemain == 0) {
//計算不整除的剩餘部分
mRemain = (int) (w - mGap) % (2 * mRadius + mGap);
}
mCircleNum = (int) ((w - mGap) / (2 * mRadius + mGap));
}
複製程式碼
- 接下來就是最重要的部分了,重寫onDraw方法,繪製自定義View,onDraw程式碼如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < mCircleNum; i++) {
//計算出要畫的圓圈的x軸位置
float x = mGap + mRadius + mRemain / 2 + ((mGap + mRadius * 2) * i);
//從x位置開始畫上面的圓圈
canvas.drawCircle(x, 0, mRadius, mPaint);
//從x位置開始畫下面的圓圈
canvas.drawCircle(x, getHeight(), mRadius, mPaint);
}
}
複製程式碼
- 至此,自定義的優惠券View已經可以使用了,讓我們把它加入到佈局檔案中,程式碼如下 :
<top.cyixlq.view.widght.QuanView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/colorPrimary">
</top.cyixlq.view.widght.QuanView>
複製程式碼
- 執行後的結果如圖所示:
- 新增自定義屬性,我們雖然能正常使用了,但是各個使用者間需求不同我們還要能夠自定義啊,這樣才能用的舒心啊!首先就要在values目錄下新建一個檔案了,attrs.xml,然後在檔案中加入以下程式碼:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name="QuanView">
<!--圓半徑大小-->
<attr name="radius" format="dimension" />
<!--圓與圓之間的間隔-->
<attr name="gap" format="dimension" />
</declare-styleable>
</resources>
複製程式碼
- 修改View的建構函式,讀取佈局檔案中傳來的引數:
public QuanView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.QuanView);
mGap = typedArray.getDimensionPixelOffset(R.styleable.QuanView_gap,20);//最後那個引數代表預設值,如果佈局檔案中沒有傳入該引數則使用預設值
mRadius = typedArray.getDimensionPixelOffset(R.styleable.QuanView_radius,15);
typedArray.recycle();
}
複製程式碼
- 在佈局檔案中加上我們的自定義的引數,程式碼如下:
<top.cyixlq.view.widght.QuanView
android:layout_width="match_parent"
android:layout_height="150dp"
app:gap="2dp"
app:radius="2dp"
android:background="@color/colorPrimary">
</top.cyixlq.view.widght.QuanView>
複製程式碼
(別忘了,使用了自定義的引數的話要引入一個名稱空間哦,如下所示)
xmlns:app="http://schemas.android.com/apk/res-auto"
複製程式碼
- 如果覺得這樣不夠帥的話,app這個欄位是可以換的,例如:
xmlns:cy="http://schemas.android.com/apk/res-auto"
複製程式碼
這時候在佈局檔案中的自定義元件的那一段程式碼報錯了
這時候僅僅需要將佈局中自定義的程式碼換成如下所示就可以了。(將app換成引入時候的名稱cy)<top.cyixlq.view.widght.QuanView
android:layout_width="match_parent"
android:layout_height="150dp"
cy:gap="2dp"
cy:radius="2dp"
android:background="@color/colorPrimary">
</top.cyixlq.view.widght.QuanView>
複製程式碼
這樣是不是就具有標誌性了呢?是不是更帥一點了呢? 最後我們再來看看修改後的效果吧!