当前位置: 代码迷 >> Android >> android UI进阶之自定义结合控件
  详细解决方案

android UI进阶之自定义结合控件

热度:87   发布时间:2016-05-01 20:21:45.0
android UI进阶之自定义组合控件

好久没写博客了。实在是忙不过来,不过再不总结总结真的不行了。慢慢来吧,有好多需要去总结的,博客里还是记录ui方面的。

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

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

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

?

[html]?view plaincopy
  1. <?xml?version="1.0"?encoding="utf-8"?>??
  2. <LinearLayout?xmlns: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,导入刚刚的布局,并且设置需要的方法,从而使的能在代码中控制这个自定义控件内容的显示。代码如下:

?

?

[java]?view plaincopy
  1. package?com.notice.ib;??
  2. ??
  3. import?android.content.Context;??
  4. import?android.util.AttributeSet;??
  5. import?android.view.LayoutInflater;??
  6. import?android.widget.ImageView;??
  7. import?android.widget.LinearLayout;??
  8. import?android.widget.TextView;??
  9. ??
  10. public?class?ImageBt?extends?LinearLayout?{??
  11. ??
  12. ????private?ImageView?iv;??
  13. ????private?TextView??tv;??
  14. ??
  15. ????public?ImageBt(Context?context)?{??
  16. ????????this(context,?null);??
  17. ????}??
  18. ??
  19. ????public?ImageBt(Context?context,?AttributeSet?attrs)?{??
  20. ????????super(context,?attrs);??
  21. ????????//?导入布局??
  22. ????????LayoutInflater.from(context).inflate(R.layout.custombt,?this,?true);??
  23. ????????iv?=?(ImageView)?findViewById(R.id.iv);??
  24. ????????tv?=?(TextView)?findViewById(R.id.tv);??
  25. ??
  26. ????}??
  27. ??
  28. ????/**?
  29. ?????*?设置图片资源?
  30. ?????*/??
  31. ????public?void?setImageResource(int?resId)?{??
  32. ????????iv.setImageResource(resId);??
  33. ????}??
  34. ??
  35. ????/**?
  36. ?????*?设置显示的文字?
  37. ?????*/??
  38. ????public?void?setTextViewText(String?text)?{??
  39. ????????tv.setText(text);??
  40. ????}??
  41. ??
  42. }??

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

?

?

[html]?view plaincopy
  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这个类中已经写好了相应的方法,简单调用即可。代码如下:

?

[java]?view plaincopy
  1. public?class?MainActivity?extends?Activity?{??
  2. ??
  3. ????private?ImageBt?ib1;??
  4. ????private?ImageBt?ib2;??
  5. ??
  6. ????/**?Called?when?the?activity?is?first?created.?*/??
  7. ????@Override??
  8. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  9. ????????super.onCreate(savedInstanceState);??
  10. ????????setContentView(R.layout.login);??
  11. ??
  12. ????????ib1?=?(ImageBt)?findViewById(R.id.bt_confirm);??
  13. ????????ib2?=?(ImageBt)?findViewById(R.id.bt_cancel);??
  14. ??
  15. ????????ib1.setTextViewText("确定");??
  16. ????????ib1.setImageResource(R.drawable.confirm);??
  17. ????????ib2.setTextViewText("取消");??
  18. ????????ib2.setImageResource(R.drawable.cancel);??
  19. ??
  20. ????????ib1.setOnClickListener(new?OnClickListener()?{??
  21. ??
  22. ????????????@Override??
  23. ????????????public?void?onClick(View?v)?{??
  24. ????????????????????//在这里可以实现点击事件??
  25. ????????????}??
  26. ????????});??
  27. ??
  28. ????}??
  29. }??

?

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

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

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

[html]?view plaincopy
  1. <?xml?version="1.0"?encoding="utf-8"?>??
  2. <RelativeLayout?xmlns: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这个接口,监听输入框中的文字变化。使用也很简单,实现他的三个方法即可。看代码:

?

[java]?view plaincopy
  1. package?com.notice.ce;??
  2. ??
  3. import?android.content.Context;??
  4. import?android.text.Editable;??
  5. import?android.text.TextWatcher;??
  6. import?android.util.AttributeSet;??
  7. import?android.view.LayoutInflater;??
  8. import?android.view.View;??
  9. import?android.widget.EditText;??
  10. import?android.widget.ImageButton;??
  11. import?android.widget.LinearLayout;??
  12. ??
  13. public?class?EditCancel?extends?LinearLayout?implements?EdtInterface?{??
  14. ??
  15. ????ImageButton?ib;??
  16. ????EditText????et;??
  17. ??
  18. ????public?EditCancel(Context?context)?{??
  19. ????????super(context);??
  20. ??
  21. ????}??
  22. ??
  23. ????public?EditCancel(Context?context,?AttributeSet?attrs)?{??
  24. ????????super(context,?attrs);??
  25. ????????LayoutInflater.from(context).inflate(R.layout.custom_editview,?this,?true);??
  26. ????????init();??
  27. ??
  28. ????}??
  29. ??
  30. ????private?void?init()?{??
  31. ????????ib?=?(ImageButton)?findViewById(R.id.ib);??
  32. ????????et?=?(EditText)?findViewById(R.id.et);??
  33. ????????et.addTextChangedListener(tw);//?为输入框绑定一个监听文字变化的监听器??
  34. ????????//?添加按钮点击事件??
  35. ????????ib.setOnClickListener(new?OnClickListener()?{??
  36. ??
  37. ????????????@Override??
  38. ????????????public?void?onClick(View?v)?{??
  39. ????????????????hideBtn();//?隐藏按钮??
  40. ????????????????et.setText("");//?设置输入框内容为空??
  41. ????????????}??
  42. ????????});??
  43. ??
  44. ????}??
  45. ??
  46. ????//?当输入框状态改变时,会调用相应的方法??
  47. ????TextWatcher?tw?=?new?TextWatcher()?{??
  48. ??
  49. ???????????????????????@Override??
  50. ???????????????????????public?void?onTextChanged(CharSequence?s,?int?start,?int?before,?int?count)?{??
  51. ???????????????????????????//?TODO?Auto-generated?method?stub??
  52. ??
  53. ???????????????????????}??
  54. ??
  55. ???????????????????????@Override??
  56. ???????????????????????public?void?beforeTextChanged(CharSequence?s,?int?start,?int?count,?int?after)?{??
  57. ???????????????????????????//?TODO?Auto-generated?method?stub??
  58. ??
  59. ???????????????????????}??
  60. ??
  61. ???????????????????????//?在文字改变后调用??
  62. ???????????????????????@Override??
  63. ???????????????????????public?void?afterTextChanged(Editable?s)?{??
  64. ???????????????????????????if?(s.length()?==?0)?{??
  65. ???????????????????????????????hideBtn();//?隐藏按钮??
  66. ???????????????????????????}?else?{??
  67. ???????????????????????????????showBtn();//?显示按钮??
  68. ???????????????????????????}??
  69. ??
  70. ???????????????????????}??
  71. ??
  72. ???????????????????};??
  73. ??
  74. ????@Override??
  75. ????public?void?hideBtn()?{??
  76. ????????//?设置按钮不可见??
  77. ????????if?(ib.isShown())?ib.setVisibility(View.GONE);??
  78. ??
  79. ????}??
  80. ??
  81. ????@Override??
  82. ????public?void?showBtn()?{??
  83. ????????//?设置按钮可见??
  84. ????????if?(!ib.isShown())?ib.setVisibility(View.VISIBLE);??
  85. ??
  86. ????}??
  87. ??
  88. }??
  89. ??
  90. interface?EdtInterface?{??
  91. ??
  92. ????public?void?hideBtn();??
  93. ??
  94. ????public?void?showBtn();??
  95. ??
  96. }??

?

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

?

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

?

?

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


  学会灵活的使用组合控件,对UI开发会有很大帮助。有什么问题可以留言交流~

1 楼 Mr_Jis 2012-04-19  
有源码就好了。
2 楼 xmllong 2012-05-18  
把用到的那几个图片发上来呀,我试了,没出来效果
  相关解决方案