首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 平面设计 > 图形图像 >

自定义控件 — 创造Checkable ImageButton

2012-07-22 
自定义控件 — 创建Checkable ImageButton创建自定义控件根据控件的需求主要有一下几种方案:1、如果现有的控

自定义控件 — 创建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文件中指定相关属性的值。

<?xml version="1.0" encoding="utf-8"?><resources>    <!-- custom checkable imageButton -->    <declare-styleable name="CheckableImageButton">        <attr name="is_checked" format="boolean"/>        <attr name="personality">            <enum name="radio" value="0"/>            <enum name="check" value="1"/>        </attr>    </declare-styleable></resources> 

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

<?xml version="1.0" encoding="UTF-8"?><selector  xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:jimi="http://schemas.android.com/apk/res/com.seclock.jimi">  <item android:state_pressed="true" android:drawable="@drawable/transparent"  />  <item jimi:is_checked="true" android:drawable="@drawable/checkable_image_btn_state_checked"  />  <item android:drawable="@drawable/transparent"  /></selector> 

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

3. 创建布局文件,可以指定自定义属性的值。
<?xml version="1.0" encoding="UTF-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:jimi="http://schemas.android.com/apk/res/com.seclock.jimi"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <you.package.name.CheckableImageButton        android:layout_width="fill_parent"        android:layout_height="fill_parent"        jimi:is_check="true"        jimi:personality="radio"    /></LinearLayout> 


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

5. 实现Checkable接口。

接口如下:

/**     * Change the checked state of the view     *      * @param checked The new checked state     */    void setChecked(boolean checked);            /**     * @return The current checked state of the view     */    boolean isChecked();        /**     * Change the checked state of the view to the inverse of its current state     *     */    void toggle(); 

自定义类全部代码:

public class CheckableImageButton extends ImageButton implements Checkable {private static final String DEBUG_TAG = CheckableImageButton.class.getSimpleName();private static final int PERSONALITY_RADIO_BUTTON = 0;private static final int PERSONALITY_CHECK_BUTTON = 1;private static final int[] CHECKED_STATE_SET = { R.attr.checked };private boolean mChecked;private int personality;private boolean mBroadcasting;private OnCheckedChangeListener mOnCheckedChangeListener;public CheckableImageButton(Context context) {super(context);}public CheckableImageButton(Context context, AttributeSet attrs,int defStyle) {super(context, attrs, defStyle);}public CheckableImageButton(Context context, AttributeSet attrs) {super(context, attrs);// 获取自定义属性的值TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.checkedImageButton);mChecked = a.getBoolean(R.styleable.checkedImageButton_checked, false);personality = a.getInt(R.styleable.checkedImageButton_personality,PERSONALITY_RADIO_BUTTON);setChecked(mChecked);// Give back a previously retrieved StyledAttributes, for later re-use.a.recycle();}@Overridepublic boolean performClick() {// 拦截点击事件处理checkif (personality == PERSONALITY_CHECK_BUTTON) {toggle();} else if (personality == PERSONALITY_RADIO_BUTTON) {setChecked(true);}return super.performClick();}@Overridepublic void setChecked(boolean checked) {Log.d(DEBUG_TAG, "setChecked:" + checked);if (mChecked != checked) {mChecked = checked;// 状态改变刷新视图refreshDrawableState();}if (mBroadcasting) {return;}mBroadcasting = true;if (null != mOnCheckedChangeListener) {mOnCheckedChangeListener.onCheckedChanged(this, mChecked);}mBroadcasting = false;}@Overridepublic boolean isChecked() {return mChecked;}@Overridepublic void toggle() {setChecked(!mChecked);}@Overridepublic int[] onCreateDrawableState(int extraSpace) {int[] states = super.onCreateDrawableState(extraSpace + 1);if (isChecked()) {mergeDrawableStates(states, CHECKED_STATE_SET);}return states;}@Overrideprotected void drawableStateChanged() {super.drawableStateChanged();// invalidate();}public static interface OnCheckedChangeListener {/** * interface definition for a callback to be invoked when the checked * image button changed *  * @param button * @param isChecked * */public void onCheckedChanged(CheckableImageButton button,boolean isChecked);}/** * @Title: 保存状态. * @author Anders */static class SaveState extends BaseSavedState {boolean checked;public SaveState(Parcel in) {super(in);checked = (Boolean) in.readValue(null);}public SaveState(Parcelable superState) {super(superState);}@Overridepublic void writeToParcel(Parcel dest, int flags) {super.writeToParcel(dest, flags);dest.writeValue(checked);}public static final Parcelable.Creator<SaveState> CREATOR = new Creator<CheckableImageButton.SaveState>() {@Overridepublic SaveState[] newArray(int size) {return new SaveState[size];}@Overridepublic SaveState createFromParcel(Parcel source) {return createFromParcel(source);}};}@Overrideprotected Parcelable onSaveInstanceState() {Parcelable superParcelable = super.onSaveInstanceState();SaveState ss = new SaveState(superParcelable);ss.checked = isChecked();return ss;}@Overrideprotected void onRestoreInstanceState(Parcelable state) {SaveState ss = (SaveState) state;super.onRestoreInstanceState(ss.getSuperState());setChecked(ss.checked);}public OnCheckedChangeListener getmOnCheckedChangeListener() {return mOnCheckedChangeListener;}public void setmOnCheckedChangeListener(OnCheckedChangeListener mOnCheckedChangeListener) {this.mOnCheckedChangeListener = mOnCheckedChangeListener;}}

热点排行