android自定義控件

當android現有的控件不能滿足我們的需求的時候,我們一般要自定義自己的控件。

自定義控件的實現並不特別難,關鍵在理解需求及注意實現的細節。

現在舉個例子實現開關按鈕的自定義控件。

需求:

1.點擊按鈕,切換開關狀態。

2.拖動按鈕,切換開關狀態。

注意細節問題:

1.用戶拖動控件的時候,有點擊屏幕的事件,這個時候註冊監聽點擊事件會被響應。說白了就是拖動和點擊混淆了。

即用戶明明想拖動的,你卻實現了拖動完成+點擊。

2.拖動是超越邊界。

3.拖動到中途停止拖動,狀態無法選擇。

解決問題方法:

1.用戶拖動控件的距離超過5,認爲用戶意圖是拖動,禁用點擊功能;否則,認爲用戶是點擊意圖,實現點擊功能。

2.拖動位置小於最小位置,設置爲0;超過最大位置,設置爲最大邊界。

3.拖動到中途的位置與中線(昨天起始位置與最大位置的中線)比較,小於中線歸爲起始狀態,大於或等於中線爲截止的狀態。

@Override
/**
* 測量尺寸時的回調方法 這個方法我以前比較少用所以這裏mark
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);

/**
* 設置當前view的大小
* width  :view的寬度
* height :view的高度   (單位:像素)
*/
setMeasuredDimension(backgroundBitmap.getWidth(),backgroundBitmap.getHeight());
}

加上自定義屬性(常用於封裝組件給自己或他人使用)

首先在res/values/attrs.xml設置

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 聲名屬性集的名稱 -->
    <declare-styleable name="MySwitchBtn">

        <!-- 聲名一個屬性  name是my_background(開關背景圖)   類型爲 引用類型      引用資源ID -->
        <attr name="my_background" format="reference" />
        <!-- 聲名一個屬性  name是my_slide_btn(開關按鈕圖)   類型爲 引用類型      引用資源ID -->
        <attr name="my_slide_btn" format="reference" />
        <!-- 聲名一個屬性  name是curr_state (初始開關狀態)  類型爲 boolean 類型-->
        <attr name="curr_state" format="boolean" />
    </declare-styleable>
</resources>

在自定義控件類中解析自定義屬性

MySwitchBtn.java

//獲得自定義的屬性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MySwitchBtn);
//獲取自定義屬性個數	
int N = ta.getIndexCount();
for (int i = 0; i < N; i++) {
<span style="white-space:pre">			</span>/*
<span style="white-space:pre">			</span> * 獲得某個屬性的ID值
<span style="white-space:pre">			</span> */
<span style="white-space:pre">			</span>int itemId = ta.getIndex(i);
<span style="white-space:pre">			</span>switch (itemId) {
<span style="white-space:pre">			</span>case R.styleable.MySwitchBtn_curr_state:
<span style="white-space:pre">				</span>currState = ta.getBoolean(itemId, false);//獲取自定義屬性value
<span style="white-space:pre">				</span>
<span style="white-space:pre">				</span>break;
<span style="white-space:pre">			</span>case R.styleable.<span style="font-family: Arial, Helvetica, sans-serif;">MySwitchBtn</span><span style="font-family: Arial, Helvetica, sans-serif;">_my_background:</span>
<span style="white-space:pre">				</span>backgroundId = ta.getResourceId(itemId, -1);//獲取背景圖片的id
<span style="white-space:pre">				</span>if(backgroundId == -1){
<span style="white-space:pre">					</span>throw new RuntimeException("請設置背景圖片");
<span style="white-space:pre">				</span>}
<span style="white-space:pre">				</span>backgroundBitmap = BitmapFactory.decodeResource(getResources(), backgroundId);
<span style="white-space:pre">				</span>
<span style="white-space:pre">				</span>break;
<span style="white-space:pre">			</span>case R.styleable.MySwitchBtn_my_slide_btn:
<span style="white-space:pre">				</span>slideBtnId = ta.getResourceId(itemId, -1);//獲取開關圖片的id
<span style="white-space:pre">				</span><span style="font-family: Arial, Helvetica, sans-serif;">if(</span><span style="font-family: Arial, Helvetica, sans-serif;">slideBtnId </span><span style="font-family: Arial, Helvetica, sans-serif;">== -1){</span><span style="white-space:pre"></span><pre name="code" class="java"><span>					</span>throw new RuntimeException("請設置背景圖片");
<span>				</span>}

slideBtn = BitmapFactory.decodeResource(getResources(), slideBtnId);

break;


default:
break;
}

}


這樣的話我們就完成了這三個自定義控件屬性的定義及獲取解析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章