自定義View之自定義設(shè)置界面欄位
在app的應(yīng)用設(shè)置中經(jīng)常會(huì)有如下所示的設(shè)置樣式,正好學(xué)習(xí)自定義view,下面我們就先實(shí)現(xiàn)一個(gè);

1.開啟新的自定義view
public class ComboBox extends RelativeLayout{
public ComboBox(Context context) {
super(context);
}
public ComboBox(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ComboBox(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
2.設(shè)置到xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.skkk.ww.costomviewdemo.MainActivity">
<com.skkk.ww.costomviewdemo.ComboBox
android:id="@+id/cb_test"
combo:title="測(cè)試一下吧"
combo:checkedContent="右側(cè)勾選框被選中"
combo:unCheckContent="右側(cè)勾選框取消選中"
combo:ischeck="true"
android:layout_width="match_parent"
android:layout_height="100dp" />
</LinearLayout>
其實(shí)這個(gè)時(shí)候運(yùn)行項(xiàng)目就可以顯示出自定義view了,但是我沒(méi)什么都沒(méi)有設(shè)置,所以只是一片空白;
3.自定義view布局
-
自定義view布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:id="@+id/ll_left" android:layout_weight="1" android:layout_margin="5dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_title_cb" android:text="Title" android:textSize="30dp" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_content_cb" android:textSize="20dp" android:text="Content" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> <CheckBox android:id="@+id/cb_select_cb" android:layout_marginRight="10dp" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="match_parent" /> </LinearLayout> -
引用布局
private void initUI(Context context) { LayoutInflater.from(context).inflate(R.layout.layout_combobox,this,true); tvTitle= (TextView) findViewById(R.id.tv_title_cb); tvContent= (TextView) findViewById(R.id.tv_content_cb); cbCombo= (CheckBox) findViewById(R.id.cb_select_cb); llLeft= (LinearLayout) findViewById(R.id.ll_left); }當(dāng)然
initUI方法還需要加入到構(gòu)造方法中,不然就沒(méi)效果了。
效果
4.自定義屬性
通過(guò)以上的操作我們就可以得到一個(gè)像模像樣的設(shè)置欄位了,當(dāng)然,所有的屬性我們都需要在java文件中修改,這不是我們想要的,我們?nèi)绾尾拍芟蛘5目丶粯釉趚ml中定義各種屬性呢?這就需要用的自定義屬性了。
-
定義屬性
1.首先我們需要新建一個(gè)文件
attrs.xml,如下圖所示:
attrs.xml2.然后具體定義屬性內(nèi)容:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ComboBox"> <attr name="title" format="string"/> <attr name="checkedContent" format="string"/> <attr name="unCheckContent" format="string"/> <attr name="ischeck" format="boolean"/> </declare-styleable> </resources> -
引用屬性
private String title,checkContent,unCheckContent; private boolean isChecked; private TextView tvTitle,tvContent; private CheckBox cbCombo; private void initAttr(Context context, AttributeSet attrs) { TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.ComboBox); title=ta.getString(R.styleable.ComboBox_title); checkContent=ta.getString(R.styleable.ComboBox_checkedContent); unCheckContent=ta.getString(R.styleable.ComboBox_unCheckContent); isChecked=ta.getBoolean(R.styleable.ComboBox_ischeck,false); //獲取完值之后我們需要調(diào)用recycle()方法來(lái)避免重新創(chuàng)建的時(shí)候的錯(cuò)誤 ta.recycle(); }我們通過(guò)獲取
TyoedArray對(duì)象來(lái)獲取到我們自定義的屬性,獲取到屬性之后在賦值到我們定義的內(nèi)部屬性里,這樣就可以調(diào)用了tvTitle.setText(title); tvContent.setText(isChecked?checkContent:unCheckContent); cbCombo.setChecked(isChecked); cbCombo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { tvContent.setText(isChecked?checkContent:unCheckContent); } }); -
使用屬性
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:combo="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.skkk.ww.costomviewdemo.MainActivity"> <com.skkk.ww.costomviewdemo.CostomScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:scaleType="fitXY" android:layout_width="match_parent" android:layout_height="100dp" android:src="@mipmap/ic_launcher" /> <com.skkk.ww.costomviewdemo.ComboBox android:id="@+id/cb_test" combo:title="這里是我們定義的標(biāo)題" combo:checkedContent="選中了,wow!" combo:unCheckContent="沒(méi)被選中,好煩躁!" combo:ischeck="true" android:layout_width="match_parent" android:layout_height="100dp" /> </LinearLayout>這樣我們可以在xml中定義我們的屬性了,效果如下:
attr2
attr3
5.自定義方法
能夠在xml中設(shè)置屬性還不夠,我們還要在java代碼中設(shè)置屬性,接下來(lái)構(gòu)造對(duì)應(yīng)的設(shè)置方法
-
設(shè)置基本屬性getter&setter方法
/** * 設(shè)置標(biāo)題 * @param title */ public void setTitle(String title){ tvTitle.setText(title); } /** * 設(shè)置勾選顯示文本 * @param checkContent */ public void setCheckContent(String checkContent) { this.checkContent = checkContent; } /** * 設(shè)置未勾選顯示文本 * @param unCheckContent */ public void setUnCheckContent(String unCheckContent) { this.unCheckContent = unCheckContent; } /** * 設(shè)置是否勾選 * @param checked */ public void setChecked(boolean checked){ cbCombo.setChecked(checked); } /** * 返回是否勾選 * @return boolean */ public boolean isChecked(){ return cbCombo.isChecked(); } -
設(shè)置點(diǎn)擊事件
當(dāng)然還有自定義view的點(diǎn)擊事件,我得需求是除開
CheckBox之外的部分響應(yīng),也就是上面對(duì)上面初始化的左邊的LinearLayout進(jìn)行點(diǎn)擊事件設(shè)置/** * 設(shè)置點(diǎn)擊事件 * @param listener 對(duì)左側(cè)文本LinearLayout設(shè)置點(diǎn)擊事件 */ public void setLeftContainerClickListener(OnClickListener listener){ this.setOnClickListener(listener); }
6.正式使用
public class MainActivity extends AppCompatActivity {
private ComboBox cbTest;
private String TAG=this.getClass().getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cbTest = (ComboBox) findViewById(R.id.cb_test);
cbTest.setLeftContainerClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (cbTest.isChecked()){
Logger.t(TAG).i("設(shè)置勾選為TRUE");
cbTest.setChecked(false);
}else {
cbTest.setChecked(true);
}
}
});
}
}
這樣就獲得了一個(gè)簡(jiǎn)單的自定義view!