Android開發自定義View之滑動按鈕與自定義屬性

尋夢-finddreams發表於2014-10-23

    寫部落格辛苦了,轉載的朋友請標明出處哦,finddreams:(http://blog.csdn.net/finddreams/article/details/40392975)  

     話不多說,先執行效果圖:

 

       

       談到自定義View,我們都知道Android系統原生內建不少的View控制元件,常用的有:

       文字控制元件TextViewEditText,圖片控制元件ImageView,按鈕控制元件 ButtonImageButton,進度條ProgressBar,單選按鈕 RadioButtonRadioGroup,核取按鈕 CheckBox  等等。

       這裡有些小細節我們要注意一下,比如說EditText繼承自TextView,而TextView是繼承View控制元件,TextViewEditText最大的區別就是前者不可編輯而後者是可以編輯的。

 

       可能很多人不是很明白Button ImageButton的區別:

       首先,Button控制元件繼承自 TextView 類,ImageButton 繼承自 ImageView,他們的繼承父類不同。

       其次,ImageButton只能顯示圖片;Button用於顯示文字。

       最後是相同點,做為按鈕控制元件都可用於響應按鈕的點選事件。

 

       系統的控制元件雖然已經很豐富了,但有時你仍然會覺得原生控制元件不能夠達到你所想要的效果,這時你就會想,能不能自己定義控制元件呢?答案是肯定的。

       通過對android原生控制元件的研究,我們可以發現android中的控制元件都是繼承View類,如textViewImageView,通過重寫相關的方法來實現新的效果,通過這個我們得到兩點:

      1.我們可以在已有控制元件的基礎上,通過重寫相關方法來實現我們的需求。

      2.繼承View類或Viewgroup,來建立我們所需要的控制元件。一般來講,通過繼承已有的控制元件,來自定義控制元件要簡單一點。

 

      下面我就通過一個滑動開關的例項來詳細說一下關於自定義控制元件的步驟:

      1、建立類繼承View View的子類。

     public class SlideSwitchButton extends View

       2、建立構造方法:

      public SlideSwitchButton(Context context);	// 在程式碼中new 物件時呼叫此方法 
      public SlideSwitchButton(Context context, AttributeSet attrs);	// 在XML佈局檔案中宣告此View,建立物件時,由系統自動呼叫
 
      public SlideSwitchButton(Context context, AttributeSet attrs, int defStyle)	// 與方法2用法一樣,只是多了一個引數:預設樣式

        

<com.finddreams.slideswitch.SlideSwitchButton
            android:id="@+id/msg_slideSwitch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dip" />
 

       通過如上的步驟即可使用滑動按鈕控制元件了,如果你想要根據滑動開關的不同狀態,處理不同的需求,或者說你想自定義滑動開關上左右兩邊顯示的文字,比如說關閉狀態時顯示已關閉/含,開啟狀態時顯示已開啟/不含等等一些反義詞。你只需要更改一下下面的程式碼

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SlideSwitchButton msgSwitch = (SlideSwitchButton)	findViewById(R.id.msg_slideSwitch);
msgSwitch.setOnSwitchChangedListener(new OnSwitchChangedListener() {
/**
 * 需要處理的業務需求
 */
@Override
public void onSwitchChanged(SlideSwitchButton obj, int status) {
switch (obj.getId()) {
case R.id.msg_slideSwitch:
Toast.makeText(MainActivity.this, "slideSwitch1 狀態:" + status, 1).show();
break;
default:
break;
}
}
});
//可以根據你的專案要求隨意定製想要顯示的反義片語
msgSwitch.setText("已開啟", "已關閉");
}
}
 

       說完自定義的控制元件,接下來談談自定義屬性這個看起來高大上的東西,一直都是使用Android系統自帶的屬性比如說backgroundidtext等,忽然說能自定義屬性,感覺還是滿厲害的。那在真實的商業專案中,自定義屬性用的到底多不多呢?很明確的告訴你不多,雖然自定義屬性做起來並不難,但是不夠實用。當然瞭如果你能做自定義屬性的話,那樣給人的感覺很高大上,很正規。話不多說,以為滑動開關控制元件加上自定義屬性為例:

       1.你需要在values目錄下面新建一個名為attrs,其實這個名字是可以任意起的,並不是說取了其他的檔名Android系統就不認識,不過出於規範通常把屬性檔案命名為attrs

       2. 首先在attrs.xml檔案中宣告可用屬性集的名稱,然後在屬性集中宣告屬性,有屬性名:name和格式:format 。

<!-- 聲名屬性集的名稱 -->
    <declare-styleable name="slideswitchbtn">
 
        <!-- 聲名一個屬性  name是bg_switch_off   型別為 引用型別      引用資源ID -->
        <attr name="bg_switch_off" format="reference" />
 
        <!-- 聲名一個屬性  name是bg_switch_on   型別為 引用型別      引用資源ID -->
        <attr name="bg_switch_on" format="reference" />
 
        <!-- 聲名一個屬性  name是switch_thumb   型別為 boolean 型別-->
        <attr name="switch_thumb" format="reference" />
        
    </declare-styleable>

注意:format 的常用型別有

       reference 引用

       color 顏色

       boolean 布林值

       dimension 尺寸值

       float 浮點值

       integer 整型值

       string 字串

       enum 布林值

       3.在佈局檔案中使用:在使用之前必須聲名名稱空間,xmlns:dreams="http://schemas.android.com/apk/res/com.finddreams.slideswitch"

說明:xmlns XML name space xml的名稱空間的縮寫; 

      dreams可為任意寫符 

      http://schemas.android.com/apk/res/  此為android固定格式,必須這樣寫

   com.finddreams.slideswitch  此應用的包名,如manifest配置檔案中package包名一致。

</pre><pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:dreams="http://schemas.android.com/apk/res/com.finddreams.slideswitch"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

 <com.finddreams.slideswitch.AttrSlideSwitchButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dip"
            dreams:bg_switch_off="@drawable/bg_switch_off"
            dreams:bg_switch_on="@drawable/bg_switch_on"
            dreams:switch_thumb="@drawable/switch_thumb" />

       4.通過在自定義view的第二個和第三個構造方法當中,通過解析 AttributeSet 物件,獲得所需要的屬性值。

//獲得自定義的屬性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.slideswitchbtn);
int N = ta.getIndexCount();
for (int i = 0; i < N; i++) {
/*
 * 獲得某個屬性的ID值
 */
int itemId = ta.getIndex(i);
switch (itemId) {
case R.styleable.slideswitchbtn_bg_switch_off:
//id預設是-1,如果沒有找到相關的id就跑出異常
mSwitch_off = ta.getResourceId(itemId, -1);
if(mSwitch_off == -1){
throw new RuntimeException("請設定關閉圖片");
}
mSwitch_off_Bit=BitmapFactory.decodeResource(resources, ta.getResourceId(itemId, -1));
break;
case R.styleable.slideswitchbtn_bg_switch_on:
mSwitch_on = ta.getResourceId(itemId, -1);
if(mSwitch_on == -1){
throw new RuntimeException("請設定開啟圖片");
}
mSwitch_on_Bit = BitmapFactory.decodeResource(getResources(), mSwitch_on);
mBmpWidth = mSwitch_on_Bit.getWidth();
mBmpHeight = mSwitch_on_Bit.getHeight();
break;
case R.styleable.slideswitchbtn_switch_thumb:
mSwitch_thumb = ta.getResourceId(itemId, -1);
if(mSwitch_on == -1){
throw new RuntimeException("請設定滑動條");
}
mSwitch_thumb_Bit = BitmapFactory.decodeResource(getResources(), mSwitch_thumb);
mThumbWidth = mSwitch_thumb_Bit.getWidth();
break;
 
default:
break;
}
}
}

5.通過以上的步驟就可以使用自定義屬性了,同樣的效果兩種不同的實現方式,不適用自定義屬性會比使用自定義屬性要方便,沒那麼麻煩,但是會讓人感覺很正規,符合Android的規範。下面上專案原始碼,有需要的朋友可以下載看看。http://download.csdn.net/detail/finddreams/8071641

相關文章