自定義控件以及自定義控件屬性
一.自定義控件
1.爲什麼要用自定義控件?
我們所有的控件都是直接或者簡介繼承自view,所用的佈局都是直接或者間接繼承自ViewGroup的。View是android中最基本的UI組件,他可以在屏幕上繪製一塊矩形區域,並且能響應這塊區域的各種事件,因此我們使用的各種控件其實就是在View的基礎上又添加了各自特有的功能。而ViewGroup則是一中隊特殊的View,他可以包含很多的子View和子ViewGroup,是一個用於放置空間和佈局的容器(引用郭霖大神的第一行代碼上),因此當系統的空間不能夠滿足我們的要求時,我們。可以自定義各種控件,例如:
(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>
這裏因爲上面的控件是RelatieLayout,因此創建一個類繼承自RelativeLayout,在這裏面我們需要做的有兩件事:第一我們
要將上面的佈局文件加載進來(inflate),第二我們要實現各個部分控件的邏輯(比如點擊過後有哪些邏輯需要實現)。
package com.blossoming.mobilesafe.UI;
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);
}
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");
{
super(context);
initView(context);
}
{
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。
二.自定義控件屬性
TextView的內容就會是”哈哈“,但是我們也可以通過在程序中textView.setText("哈哈"),這兩者有什麼聯繫???
其實這就是自定義屬性的體現,即比較方便(上面的是我個人的理解)。那麼我們能不能給我們的自定義控件加上我們的自定義屬
呢?當然可以。下面我貼出代碼
<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>
這個就是在佈局文件中引入了我們自定義的控件,這裏我們發現了一個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="設置自動更新已經關閉"
義控件的第二個構造函數裏的getAttributeValue即得到我們屬性的值。但是這個值有什麼用呢,這裏面有個邏輯就是當我們點擊
控件的時候我們需要切換文字(開啓關閉),我們只用利用get到的屬性值,通過setText來設置就ok了。
三.應用場景
只需改變一下我們自定義的屬性值是不是就ok了呢。確實很方便啊,很符合現在人偷懶的性格啊。