`

自定义控件 — 创建Checkable ImageButton

 
阅读更多
创建自定义控件根据控件的需求主要有一下几种方案:

1、如果现有的控件已经具备了你想要的功能,那么修改或者扩展它们的外观或行为。通过override事件处理函数和onDraw,仍然调用父类的方法,在你定制控件时就不需要重新实现它的功能。
2、组合控件来创建原子的、可重用的widgets,它会引发一些相互关联的控件的功能性发生变化。例如,你可以创建一个下拉的combobox,通过组合一个TextView和一个Button,当点击Button时,显示一个浮动的ListView。

3、当你需要一个完全不同的界面,而不能通过改变和组合现有的控件来达到的时候,选择创建一个全新的控件。

CheckableImageButton

Android自带的ImageButton是不支持像CheckBox, RadioButton拥有的check(选中)状态的,Android提供的组件还算丰富,我们能用这些组件快速开发一个简单的应用程序,但在比较复杂项目中就会感觉捉襟见肘了,但幸好在Android系统上开发者能自由定制自己的UI组件,来弥补现有组件的不足。

创建一个CheckableImageButton需要做的工作:

1. 添加资源文件 res/values/attrs.xml,添加自定义组件CheckableImageButton,声明is_checked和personality属性,以后就能通过这两个属性在XML文件中指定相关属性的值。

Java代码收藏代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <resources>
  3. <!--customcheckableimageButton-->
  4. <declare-styleablename="CheckableImageButton">
  5. <attrname="is_checked"format="boolean"/>
  6. <attrname="personality">
  7. <enumname="radio"value="0"/>
  8. <enumname="check"value="1"/>
  9. </attr>
  10. </declare-styleable>
  11. </resources>

2. 创建ImageButton的背景,使用Selector Drawable。

Java代码收藏代码
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <selectorxmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:jimi="http://schemas.android.com/apk/res/com.seclock.jimi">
  4. <itemandroid:state_pressed="true"android:drawable="@drawable/transparent"/>
  5. <itemjimi:is_checked="true"android:drawable="@drawable/checkable_image_btn_state_checked"/>
  6. <itemandroid:drawable="@drawable/transparent"/>
  7. </selector>

jimi:is_checked="true"是(1)中自定义的属性

3. 创建布局文件,可以指定自定义属性的值。
Java代码收藏代码
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:jimi="http://schemas.android.com/apk/res/com.seclock.jimi"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <you.package.name.CheckableImageButton
  7. android:layout_width="fill_parent"
  8. android:layout_height="fill_parent"
  9. jimi:is_check="true"
  10. jimi:personality="radio"
  11. />
  12. </LinearLayout>


4. 创建自定义类,继承至ImageButton。让自定义类有ImageButton的所有功能。在构造方法中通过TypedArray读取自定义属性的值。

5. 实现Checkable接口。

接口如下:

Java代码收藏代码
  1. /**
  2. *Changethecheckedstateoftheview
  3. *
  4. *@paramcheckedThenewcheckedstate
  5. */
  6. voidsetChecked(booleanchecked);
  7. /**
  8. *@returnThecurrentcheckedstateoftheview
  9. */
  10. booleanisChecked();
  11. /**
  12. *Changethecheckedstateoftheviewtotheinverseofitscurrentstate
  13. *
  14. */
  15. voidtoggle();

自定义类全部代码:

Java代码收藏代码
  1. publicclassCheckableImageButtonextendsImageButtonimplementsCheckable{
  2. privatestaticfinalStringDEBUG_TAG=CheckableImageButton.class
  3. .getSimpleName();
  4. privatestaticfinalintPERSONALITY_RADIO_BUTTON=0;
  5. privatestaticfinalintPERSONALITY_CHECK_BUTTON=1;
  6. privatestaticfinalint[]CHECKED_STATE_SET={R.attr.checked};
  7. privatebooleanmChecked;
  8. privateintpersonality;
  9. privatebooleanmBroadcasting;
  10. privateOnCheckedChangeListenermOnCheckedChangeListener;
  11. publicCheckableImageButton(Contextcontext){
  12. super(context);
  13. }
  14. publicCheckableImageButton(Contextcontext,AttributeSetattrs,
  15. intdefStyle){
  16. super(context,attrs,defStyle);
  17. }
  18. publicCheckableImageButton(Contextcontext,AttributeSetattrs){
  19. super(context,attrs);
  20. //获取自定义属性的值
  21. TypedArraya=context.obtainStyledAttributes(attrs,
  22. R.styleable.checkedImageButton);
  23. mChecked=a.getBoolean(R.styleable.checkedImageButton_checked,false);
  24. personality=a.getInt(R.styleable.checkedImageButton_personality,
  25. PERSONALITY_RADIO_BUTTON);
  26. setChecked(mChecked);
  27. //GivebackapreviouslyretrievedStyledAttributes,forlaterre-use.
  28. a.recycle();
  29. }
  30. @Override
  31. publicbooleanperformClick(){
  32. //拦截点击事件处理check
  33. if(personality==PERSONALITY_CHECK_BUTTON){
  34. toggle();
  35. }elseif(personality==PERSONALITY_RADIO_BUTTON){
  36. setChecked(true);
  37. }
  38. returnsuper.performClick();
  39. }
  40. @Override
  41. publicvoidsetChecked(booleanchecked){
  42. Log.d(DEBUG_TAG,"setChecked:"+checked);
  43. if(mChecked!=checked){
  44. mChecked=checked;
  45. //状态改变刷新视图
  46. refreshDrawableState();
  47. }
  48. if(mBroadcasting){
  49. return;
  50. }
  51. mBroadcasting=true;
  52. if(null!=mOnCheckedChangeListener){
  53. mOnCheckedChangeListener.onCheckedChanged(this,mChecked);
  54. }
  55. mBroadcasting=false;
  56. }
  57. @Override
  58. publicbooleanisChecked(){
  59. returnmChecked;
  60. }
  61. @Override
  62. publicvoidtoggle(){
  63. setChecked(!mChecked);
  64. }
  65. @Override
  66. publicint[]onCreateDrawableState(intextraSpace){
  67. int[]states=super.onCreateDrawableState(extraSpace+1);
  68. if(isChecked()){
  69. mergeDrawableStates(states,CHECKED_STATE_SET);
  70. }
  71. returnstates;
  72. }
  73. @Override
  74. protectedvoiddrawableStateChanged(){
  75. super.drawableStateChanged();
  76. //invalidate();
  77. }
  78. publicstaticinterfaceOnCheckedChangeListener{
  79. /**
  80. *interfacedefinitionforacallbacktobeinvokedwhenthechecked
  81. *imagebuttonchanged
  82. *
  83. *@parambutton
  84. *@paramisChecked
  85. **/
  86. publicvoidonCheckedChanged(CheckableImageButtonbutton,
  87. booleanisChecked);
  88. }
  89. /**
  90. *@Title:保存状态.
  91. *@authorAnders
  92. */
  93. staticclassSaveStateextendsBaseSavedState{
  94. booleanchecked;
  95. publicSaveState(Parcelin){
  96. super(in);
  97. checked=(Boolean)in.readValue(null);
  98. }
  99. publicSaveState(ParcelablesuperState){
  100. super(superState);
  101. }
  102. @Override
  103. publicvoidwriteToParcel(Parceldest,intflags){
  104. super.writeToParcel(dest,flags);
  105. dest.writeValue(checked);
  106. }
  107. publicstaticfinalParcelable.Creator<SaveState>CREATOR=newCreator<CheckableImageButton.SaveState>(){
  108. @Override
  109. publicSaveState[]newArray(intsize){
  110. returnnewSaveState[size];
  111. }
  112. @Override
  113. publicSaveStatecreateFromParcel(Parcelsource){
  114. returncreateFromParcel(source);
  115. }
  116. };
  117. }
  118. @Override
  119. protectedParcelableonSaveInstanceState(){
  120. ParcelablesuperParcelable=super.onSaveInstanceState();
  121. SaveStatess=newSaveState(superParcelable);
  122. ss.checked=isChecked();
  123. returnss;
  124. }
  125. @Override
  126. protectedvoidonRestoreInstanceState(Parcelablestate){
  127. SaveStatess=(SaveState)state;
  128. super.onRestoreInstanceState(ss.getSuperState());
  129. setChecked(ss.checked);
  130. }
  131. publicOnCheckedChangeListenergetmOnCheckedChangeListener(){
  132. returnmOnCheckedChangeListener;
  133. }
  134. publicvoidsetmOnCheckedChangeListener(
  135. OnCheckedChangeListenermOnCheckedChangeListener){
  136. this.mOnCheckedChangeListener=mOnCheckedChangeListener;
  137. }
  138. }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics