初學android-自定義控件以及控件屬性

                                          自定義控件以及自定義控件屬性


一.自定義控件

                                                   
       
1.爲什麼要用自定義控件?
我們所有的控件都是直接或者簡介繼承自view,所用的佈局都是直接或者間接繼承自ViewGroup的。View是android中最基本的UI組件,他可以在屏幕上繪製一塊矩形區域,並且能響應這塊區域的各種事件,因此我們使用的各種控件其實就是在View的基礎上又添加了各自特有的功能。而ViewGroup則是一中隊特殊的View,他可以包含很多的子View和子ViewGroup,是一個用於放置空間和佈局的容器(引用郭霖大神的第一行代碼上),因此當系統的空間不能夠滿足我們的要求時,我們。可以自定義各種控件,例如:

這些控件可以被反覆利用,我們不想在用到的時候反覆寫,因此可以創建我們自己的控件。

2.怎麼創建自定義控件?
(1)所見即所得:寫佈局文件
既然是控件,那麼他肯定是有形狀有作用的,我們可以通過佈局文件將其描述出來(這裏我寫一個軟件經常用到的控件,在很多軟件的設置裏都有開啓/關閉某項功能的選項,這個控件需要反覆利用,上面第三個控件),所見即所得,這個控件包含4個控件,即兩個TextView和一個CheckBox還有一個View(下劃線),那就順理成章的寫出佈局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="70dp">
    <TextView
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:textSize="22dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_setting_text"
        android:text="設置是否進行自動更新"
        android:textColor="#000000"/>
    <TextView
        android:layout_marginLeft="10dp"
        android:textSize="20dp"
        android:layout_below="@id/tv_setting_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_setting_content"/>
//這裏的clickable和focusable是爲了後來能夠點擊整個控件進行選擇而不是隻能點擊CheckBox
    <CheckBox
        android:clickable="false"
        android:focusable="false"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:id="@+id/cb_setting_choose"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <View
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_width="wrap_content"
        android:layout_height="0.5dp"
        android:layout_alignParentBottom="true"
        android:background="#000000"
        ></View>
</RelativeLayout>

(2)靜態頁面給他添加邏輯:創建控件的類實現某些邏輯
這裏因爲上面的控件是RelatieLayout,因此創建一個類繼承自RelativeLayout,在這裏面我們需要做的有兩件事:第一我們
要將上面的佈局文件加載進來(inflate),第二我們要實現各個部分控件的邏輯(比如點擊過後有哪些邏輯需要實現)。
package com.blossoming.mobilesafe.UI;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.blossoming.mobilesafe.R;
/**
 * Created by Blossoming on 2016/8/3.
 */
public class SettingItemUI extends RelativeLayout {
    private TextView tv_setting_content;
    private CheckBox cb_setting_choose;
    private String title,desc_on,desc_off;
    private void initView(Context context)
    {
        View.inflate(context, R.layout.setting_item,this);
        tv_setting_content=(TextView) findViewById(R.id.tv_setting_content);
        cb_setting_choose=(CheckBox) findViewById(R.id.cb_setting_choose);
        //  title=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","title");

    }
    public SettingItemUI(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    public SettingItemUI(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
        desc_on=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","desc_on");
        desc_off=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","desc_off");

    }

    public SettingItemUI(Context context)
    {
        super(context);
        initView(context);
    }

    public void setChecked(boolean bool)
    {
        if(bool) {
            cb_setting_choose.setChecked(bool);
            setText(desc_off);
        }
        else
        {
            cb_setting_choose.setChecked(bool);
            setText(desc_on);
        }
    }
    public boolean getChecked()
    {
        return cb_setting_choose.isChecked();
    }
    public void setText(String text)
    {
        tv_setting_content.setText(text);
    }
}

下面我們細說一下過程:一開始我們需要導入3個構造方法,每個構造方法中都需要加載自定義的佈局文件,其中我們注意到第二個
構造方法中getAttributeValue( , ),這個函數作用是的到我們自定義控件屬性的具體的值(暫時不說)。加載進佈局之後我
們就要寫邏輯了,當點擊控件之後我們需要實現CheckBox打勾/取消打勾,因此自然有方法setChecked,點擊之後傳入bool值,
但是我們還需要獲取點擊之前的狀態,因此自然有了getChecked來獲取控件的狀態;在點擊之後我們需要改變第二個TextView
的內容(自動更新已經開啓/關閉),因此自然有方法setText。

二.自定義控件屬性


1.自定義控件屬性只是自定義控件裏的一個小技巧,我們舉個例子:在TextView的佈局文件中我們可以這樣寫text=”哈哈“,那麼
TextView的內容就會是”哈哈“,但是我們也可以通過在程序中textView.setText("哈哈"),這兩者有什麼聯繫???
其實這就是自定義屬性的體現,即比較方便(上面的是我個人的理解)。那麼我們能不能給我們的自定義控件加上我們的自定義屬
呢?當然可以。下面我貼出代碼

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:blossoming="http://schemas.android.com/apk/com.blossoming.mobilesafe"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
        <com.blossoming.mobilesafe.UI.SettingItemUI
            blossoming:title_item="設置是否進行自動更新"
            blossoming:desc_on="自動更新已經開啓"
            blossoming:desc_off="自動更新已經關閉"
            android:id="@+id/si"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </com.blossoming.mobilesafe.UI.SettingItemUI>

</LinearLayout>
這個就是在佈局文件中引入了我們自定義的控件,這裏我們發現了一個android中沒有的屬性blossoming,這個其實就是我自定義
的屬性,步驟如下:
①自定義命名空間,例如:
  xmlns:blossoming(可以任意)="http://schemas.android.com/apk/res/《包名》"
  xmlns:="http://schemas.android.com/apk/res/com.itheima.mobilesafe"


②自定義我們的屬性,在Res/values/attrs.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>


    <declare-styleable name="TextView">
        <attr name="title_item" format="string" />
        <attr name="desc_on" format="string" />
        <attr name="desc_off" format="string" />
    </declare-styleable>


</resources>


③使用我們自定義的屬性
 例如:
        itheima:title="設置自動更新"
        itheima:desc_on="設置自動更新已經開啓"
        itheima:desc_off="設置自動更新已經關閉"

2.這些屬性並沒有生命,即到現在我們並沒有使用,我們要在我們自定義控件的類當中去get到這些屬性的值,這裏回到上面的自定
義控件的第二個構造函數裏的getAttributeValue即得到我們屬性的值。但是這個值有什麼用呢,這裏面有個邏輯就是當我們點擊
控件的時候我們需要切換文字(開啓關閉),我們只用利用get到的屬性值,通過setText來設置就ok了。

三.應用場景


如果我們又需要寫一個控件來設置軟件是否能夠通過在4G網絡下訪問網絡,那麼們只需要在大的佈局文件里加入我們自定義的控件,
只需改變一下我們自定義的屬性值是不是就ok了呢。確實很方便啊,很符合現在人偷懶的性格啊。




發佈了35 篇原創文章 · 獲贊 55 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章