本文轉自:http://www.cnblogs.com/delia/archive/2012/03/09/2387934.html
今天和大家分享下組合控件的使用。很多時候android自定義控件並不能滿足需求,如何做呢?很多方法,可以自己繪制一個,可以通過繼承基礎控件來重寫某些環節,當然也可以將控件組合成一個新控件,這也是最方便的一個方法。今天就來介紹下如何使用組合控件,將通過兩個實例來介紹。第一個實現一個帶圖片和文字的按鈕,如圖所示:
整個過程可以分四步走。第一步,定義一個layout,實現按鈕內部的布局。代碼如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/iv"
- android:src="@drawable/confirm"
- android:paddingTop="5dip"
- android:paddingBottom="5dip"
- android:paddingLeft="40dip"
- android:layout_gravity="center_vertical"
- />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="確定"
- android:textColor="#000000"
- android:id="@+id/tv"
- android:layout_marginLeft="8dip"
- android:layout_gravity="center_vertical"
- />
- </LinearLayout>
這個xml實現一個左圖右字的布局,接下來寫一個類繼承LinearLayout,導入剛剛的布局,並且設置需要的方法,從而使的能在代碼中控制這個自定義控件內容的顯示。代碼如下:
- package com.notice.ib;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- publicclass ImageBt extends LinearLayout {
- private ImageView iv;
- private TextView tv;
- public ImageBt(Context context) {
- this(context, null);
- }
- public ImageBt(Context context, AttributeSet attrs) {
- super(context, attrs);
- // 導入布局
- LayoutInflater.from(context).inflate(R.layout.custombt, this, true);
- iv = (ImageView) findViewById(R.id.iv);
- tv = (TextView) findViewById(R.id.tv);
- }
- /**
- * 設置圖片資源
- */
- publicvoid setImageResource(int resId) {
- iv.setImageResource(resId);
- }
- /**
- * 設置顯示的文字
- */
- publicvoid setTextViewText(String text) {
- tv.setText(text);
- }
- }
第三步,在需要使用這個自定義控件的layout中加入這控件,只需要在xml中加入即可。方法如下:
- <RelativeLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- >
- <com.notice.ib.ImageBt
- android:id="@+id/bt_confirm"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="@drawable/btbg"
- android:clickable="true"
- android:focusable="true"
- />
- <com.notice.ib.ImageBt
- android:id="@+id/bt_cancel"
- android:layout_toRightOf="@id/bt_confirm"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="@drawable/btbg"
- android:clickable="true"
- android:focusable="true"
- />
- </RelativeLayout>
注意的是,控件標簽使用完整的類名即可。為了給按鈕一個點擊效果,你需要給他一個selector背景,這里就不說了。
最后一步,即在activity中設置該控件的內容。當然,在xml中也可以設置,但是只能設置一個,當我們需要兩次使用這樣的控件,並且顯示內容不同時就不行了。在activity中設置也非常簡單,我們在ImageBt這個類中已經寫好了相應的方法,簡單調用即可。代碼如下:
- publicclass MainActivity extends Activity {
- private ImageBt ib1;
- private ImageBt ib2;
- /** Called when the activity is first created. */
- @Override
- publicvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.login);
- ib1 = (ImageBt) findViewById(R.id.bt_confirm);
- ib2 = (ImageBt) findViewById(R.id.bt_cancel);
- ib1.setTextViewText("確定");
- ib1.setImageResource(R.drawable.confirm);
- ib2.setTextViewText("取消");
- ib2.setImageResource(R.drawable.cancel);
- ib1.setOnClickListener(new OnClickListener() {
- @Override
- publicvoid onClick(View v) {
- //在這里可以實現點擊事件
- }
- });
- }
- }
這樣,一個帶文字和圖片的組合按鈕控件就完成了。這樣梳理一下,使用還是非常簡單的。組合控件能做的事還非常多,主要是在類似上例中的ImageBt類中寫好要使用的方法即可。
再來看一個組合控件,帶刪除按鈕的EidtText。即在用戶輸入后,會出現刪除按鈕,點擊即可取消用戶輸入。
定義方法和上例一樣。首先寫一個自定義控件的布局:
- <?xmlversion="1.0"encoding="utf-8"?>
- <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <EditText
- android:id="@+id/et"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- />
- <ImageButton
- android:id="@+id/ib"
- android:visibility="gone"
- android:src="@drawable/menu_delete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="#00000000"
- android:layout_alignRight="@+id/et"/>
- </RelativeLayout>
實現輸入框右側帶按鈕效果,注意將按鈕隱藏。然后寫一個EditCancel類,實現刪除用戶輸入功能。這里用到了TextWatch這個接口,監聽輸入框中的文字變化。使用也很簡單,實現他的三個方法即可。看代碼:
- package com.notice.ce;
- import android.content.Context;
- import android.text.Editable;
- import android.text.TextWatcher;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.EditText;
- import android.widget.ImageButton;
- import android.widget.LinearLayout;
- publicclass EditCancel extends LinearLayout implements EdtInterface {
- ImageButton ib;
- EditText et;
- public EditCancel(Context context) {
- super(context);
- }
- public EditCancel(Context context, AttributeSet attrs) {
- super(context, attrs);
- LayoutInflater.from(context).inflate(R.layout.custom_editview, this, true);
- init();
- }
- privatevoid init() {
- ib = (ImageButton) findViewById(R.id.ib);
- et = (EditText) findViewById(R.id.et);
- et.addTextChangedListener(tw);// 為輸入框綁定一個監聽文字變化的監聽器
- // 添加按鈕點擊事件
- ib.setOnClickListener(new OnClickListener() {
- @Override
- publicvoid onClick(View v) {
- hideBtn();// 隱藏按鈕
- et.setText("");// 設置輸入框內容為空
- }
- });
- }
- // 當輸入框狀態改變時,會調用相應的方法
- TextWatcher tw = new TextWatcher() {
- @Override
- publicvoid onTextChanged(CharSequence s, int start, int before, int count) {
- // TODO Auto-generated method stub
- }
- @Override
- publicvoid beforeTextChanged(CharSequence s, int start, int count, int after) {
- // TODO Auto-generated method stub
- }
- // 在文字改變后調用
- @Override
- publicvoid afterTextChanged(Editable s) {
- if (s.length() == 0) {
- hideBtn();// 隱藏按鈕
- } else {
- showBtn();// 顯示按鈕
- }
- }
- };
- @Override
- publicvoid hideBtn() {
- // 設置按鈕不可見
- if (ib.isShown()) ib.setVisibility(View.GONE);
- }
- @Override
- publicvoid showBtn() {
- // 設置按鈕可見
- if (!ib.isShown()) ib.setVisibility(View.VISIBLE);
- }
- }
- interface EdtInterface {
- publicvoid hideBtn();
- publicvoid showBtn();
- }
在TextWatch接口的afterTextChanged方法中對文字進行判斷,若長度為0,就隱藏按鈕,否則,顯示按鈕。
另外,實現ImageButton(即那個叉)的點擊事件,刪除輸入框中的內容,並隱藏按鈕。
后面兩步的實現就是加入到實際布局中,就不再寫出來了,和上例的步驟一樣的。最后顯示效果如圖: