转载 Android自定义控件

来源:互联网 发布:截断数据库日志 编辑:程序博客网 时间:2024/06/07 02:18

今天和大家分享下组合控件的使用。很多时候android自定义控件并不能满足需求,如何做呢?很多方法,可以自己绘制一个,可以通过继承基础控件来重写某些环节,当然也可以将控件组合成一个新控件,这也是最方便的一个方法。今天就来介绍下如何使用组合控件,将通过两个实例来介绍。

第一个实现一个带图片和文字的按钮,如图所示:

整个过程可以分四步走。第一步,定义一个layout,实现按钮内部的布局。代码如下:

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

  3. android:orientation="horizontal"

  4. android:layout_width="fill_parent"

  5. android:layout_height="fill_parent"

  6. >

  7. <ImageView

  8. android:layout_width="wrap_content"

  9. android:layout_height="wrap_content"

  10. android:id="@+id/iv"

  11. android:src="@drawable/confirm"

  12. android:paddingTop="5dip"

  13. android:paddingBottom="5dip"

  14. android:paddingLeft="40dip"

  15. android:layout_gravity="center_vertical"

  16. />

  17. <TextView

  18. android:layout_width="wrap_content"

  19. android:layout_height="wrap_content"

  20. android:text="确定"

  21. android:textColor="#000000"

  22. android:id="@+id/tv"

  23. android:layout_marginLeft="8dip"

  24. android:layout_gravity="center_vertical"

  25. />

  26. </LinearLayout>

这个xml实现一个左图右字的布局,接下来写一个类继承LinearLayout,导入刚刚的布局,并且设置需要的方法,从而使的能在代码中控制这个自定义控件内容的显示。代码如下:

  1. package com.notice.ib;  

  2. import android.content.Context;  

  3. import android.util.AttributeSet;  

  4. import android.view.LayoutInflater;  

  5. import android.widget.ImageView;  

  6. import android.widget.LinearLayout;  

  7. import android.widget.TextView;  

  8. publicclass ImageBt extends LinearLayout {  

  9. private ImageView iv;  

  10. private TextView  tv;  

  11. public ImageBt(Context context) {  

  12. this(context, null);  

  13.    }  

  14. public ImageBt(Context context, AttributeSet attrs) {  

  15. super(context, attrs);  

  16. // 导入布局

  17.        LayoutInflater.from(context).inflate(R.layout.custombt, this, true);  

  18.        iv = (ImageView) findViewById(R.id.iv);  

  19.        tv = (TextView) findViewById(R.id.tv);  

  20.    }  

  21. /**

  22.     * 设置图片资源

  23.     */

  24. publicvoid setImageResource(int resId) {  

  25.        iv.setImageResource(resId);  

  26.    }  

  27. /**

  28.     * 设置显示的文字

  29.     */

  30. publicvoid setTextViewText(String text) {  

  31.        tv.setText(text);  

  32.    }  

  33. }  

第三步,在需要使用这个自定义控件的layout中加入这控件,只需要在xml中加入即可。方法如下:

  1. <RelativeLayout

  2. android:orientation="horizontal"

  3. android:layout_width="fill_parent"

  4. android:layout_height="wrap_content"

  5. android:layout_gravity="bottom"

  6. >

  7. <com.notice.ib.ImageBt

  8. android:id="@+id/bt_confirm"

  9. android:layout_height="wrap_content"

  10. android:layout_width="wrap_content"

  11. android:layout_alignParentBottom="true"

  12. android:background="@drawable/btbg"

  13. android:clickable="true"

  14. android:focusable="true"

  15. />

  16. <com.notice.ib.ImageBt

  17. android:id="@+id/bt_cancel"

  18. android:layout_toRightOf="@id/bt_confirm"

  19. android:layout_height="wrap_content"

  20. android:layout_width="wrap_content"

  21. android:layout_alignParentBottom="true"

  22. android:background="@drawable/btbg"

  23. android:clickable="true"

  24. android:focusable="true"

  25. />

  26. </RelativeLayout>

注意的是,控件标签使用完整的类名即可。为了给按钮一个点击效果,你需要给他一个selector背景,这里就不说了。

最后一步,即在activity中设置该控件的内容。当然,在xml中也可以设置,但是只能设置一个,当我们需要两次使用这样的控件,并且显示内容不同时就不行了。在activity中设置也非常简单,我们在ImageBt这个类中已经写好了相应的方法,简单调用即可。代码如下:

  1. publicclass MainActivity extends Activity {  

  2. private ImageBt ib1;  

  3. private ImageBt ib2;  

  4. /** Called when the activity is first created. */

  5. @Override

  6. publicvoid onCreate(Bundle savedInstanceState) {  

  7. super.onCreate(savedInstanceState);  

  8.        setContentView(R.layout.login);  

  9.        ib1 = (ImageBt) findViewById(R.id.bt_confirm);  

  10.        ib2 = (ImageBt) findViewById(R.id.bt_cancel);  

  11.        ib1.setTextViewText("确定");  

  12.        ib1.setImageResource(R.drawable.confirm);  

  13.        ib2.setTextViewText("取消");  

  14.        ib2.setImageResource(R.drawable.cancel);  

  15.        ib1.setOnClickListener(new OnClickListener() {  

  16. @Override

  17. publicvoid onClick(View v) {  

  18. //在这里可以实现点击事件

  19.            }  

  20.        });  

  21.    }  

  22. }  

这样,一个带文字和图片的组合按钮控件就完成了。这样梳理一下,使用还是非常简单的。组合控件能做的事还非常多,主要是在类似上例中的ImageBt类中写好要使用的方法即可。

再来看一个组合控件,带删除按钮的EidtText。即在用户输入后,会出现删除按钮,点击即可取消用户输入。

定义方法和上例一样。首先写一个自定义控件的布局:

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="fill_parent"

  4. android:layout_height="fill_parent"

  5. >

  6. <EditText

  7. android:id="@+id/et"

  8. android:layout_width="fill_parent"

  9. android:layout_height="wrap_content"

  10. android:singleLine="true"

  11. />

  12. <ImageButton

  13. android:id="@+id/ib"

  14. android:visibility="gone"

  15. android:src="@drawable/menu_delete"

  16. android:layout_width="wrap_content"

  17. android:layout_height="wrap_content"

  18. android:background="#00000000"

  19. android:layout_alignRight="@+id/et"/>

  20. </RelativeLayout>

实现输入框右侧带按钮效果,注意将按钮隐藏。然后写一个EditCancel类,实现删除用户输入功能。这里用到了TextWatch这个接口,监听输入框中的文字变化。使用也很简单,实现他的三个方法即可。看代码:

  1. package com.notice.ce;  

  2. import android.content.Context;  

  3. import android.text.Editable;  

  4. import android.text.TextWatcher;  

  5. import android.util.AttributeSet;  

  6. import android.view.LayoutInflater;  

  7. import android.view.View;  

  8. import android.widget.EditText;  

  9. import android.widget.ImageButton;  

  10. import android.widget.LinearLayout;  

  11. publicclass EditCancel extends LinearLayout implements EdtInterface {  

  12.    ImageButton ib;  

  13.    EditText    et;  

  14. public EditCancel(Context context) {  

  15. super(context);  

  16.    }  

  17. public EditCancel(Context context, AttributeSet attrs) {  

  18. super(context, attrs);  

  19.        LayoutInflater.from(context).inflate(R.layout.custom_editview, this, true);  

  20.        init();  

  21.    }  

  22. privatevoid init() {  

  23.        ib = (ImageButton) findViewById(R.id.ib);  

  24.        et = (EditText) findViewById(R.id.et);  

  25.        et.addTextChangedListener(tw);// 为输入框绑定一个监听文字变化的监听器

  26. // 添加按钮点击事件

  27.        ib.setOnClickListener(new OnClickListener() {  

  28. @Override

  29. publicvoid onClick(View v) {  

  30.                hideBtn();// 隐藏按钮

  31.                et.setText("");// 设置输入框内容为空

  32.            }  

  33.        });  

  34.    }  

  35. // 当输入框状态改变时,会调用相应的方法

  36.    TextWatcher tw = new TextWatcher() {  

  37. @Override

  38. publicvoid onTextChanged(CharSequence s, int start, int before, int count) {  

  39. // TODO Auto-generated method stub

  40.                       }  

  41. @Override

  42. publicvoid beforeTextChanged(CharSequence s, int start, int count, int after) {  

  43. // TODO Auto-generated method stub

  44.                       }  

  45. // 在文字改变后调用

  46. @Override

  47. publicvoid afterTextChanged(Editable s) {  

  48. if (s.length() == 0) {  

  49.                               hideBtn();// 隐藏按钮

  50.                           } else {  

  51.                               showBtn();// 显示按钮

  52.                           }  

  53.                       }  

  54.                   };  

  55. @Override

  56. publicvoid hideBtn() {  

  57. // 设置按钮不可见

  58. if (ib.isShown()) ib.setVisibility(View.GONE);  

  59.    }  

  60. @Override

  61. publicvoid showBtn() {  

  62. // 设置按钮可见

  63. if (!ib.isShown()) ib.setVisibility(View.VISIBLE);  

  64.    }  

  65. }  

  66. interface EdtInterface {  

  67. publicvoid hideBtn();  

  68. publicvoid showBtn();  

  69. }  

在TextWatch接口的afterTextChanged方法中对文字进行判断,若长度为0,就隐藏按钮,否则,显示按钮。

另外,实现ImageButton(即那个叉)的点击事件,删除输入框中的内容,并隐藏按钮。

后面两步的实现就是加入到实际布局中,就不再写出来了,和上例的步骤一样的。最后显示效果如图:



0 0