如何使用自定义选择器状态实现自定义视图?

时间:2014-02-21 09:41:02

标签: android android-custom-view android-selector

我想创建一个显示图片的CustomView。单击视图应更改其状态。视图可以表示三种状态(关闭,设置,未设置)。我想用XML中的选择器来做这件事。它不一定需要是自定义选择器。我可以重用选择器的三个状态(如果状态的名称不同则无关紧要。)

有没有很好的方法来实现这个目标?

1 个答案:

答案 0 :(得分:15)

以防您的问题尚未解决。我使用Android Button的新实现来更改状态。

状态在.xml中定义,并通过选择器设置。这里是 attrs.xml 文件中定义的三种状态:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="states">
        <attr name="state_on" format="boolean" />
        <attr name="state_off" format="boolean" />
        <attr name="state_notset" format="boolean" />
    </declare-styleable>
</resources>

drawables 文件夹中的选择器( statebutton_selector.xml ): (我假设启用特定状态会自动禁用其他状态 - 像“state_on”这样的drawable只是代表各个状态的.png图像)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.example.statebuttontest">
<item
    app:state_on="true"
    app:state_off="false"
    app:state_notset="false"
    android:drawable="@drawable/state_on" />
<item
    app:state_on="false"
    app:state_off="true"
    app:state_notset="false"
    android:drawable="@drawable/state_off" />
<item
    app:state_on="false"
    app:state_off="false"
    app:state_notset="true" 
    android:drawable="@drawable/state_notset" />
</selector>

另外,请注意在选择器xml文件中引用正确的程序包名称,如清单文件中所述:

xmlns:app="http://schemas.android.com/apk/res/com.example.statebuttontest"

最后,扩展StateButton的{​​{1}}类。使用简单的Button,状态会发生变化。我还实现了一个OnClickListener,例如可以由包含Button的Activity实现,并且只要状态发生变化就会被调用。

状态的更改是在OnStateChangedListener方法内完成的,每次单击按钮时,该方法都会自动 。 “extraspace + 1”表示在drawableStates数组中会有一个额外的状态。

onCreateDrawableState(...)

最后但并非最不重要的是,将选择器设置为public class StateButton extends Button implements OnClickListener { private static final int[] mStates = { R.attr.state_notset, R.attr.state_on, R.attr.state_off }; private int mStateIndex = 0; // first state is "notset" private OnStateChangedListener mListener; public StateButton(Context context, AttributeSet attrs) { super(context, attrs); setOnClickListener(this); } @Override public void onClick(View v) { changeState(); } public void changeState() { mStateIndex = (mStateIndex+1) % mStates.length; // notify listener if(mListener != null) mListener.onStateChanged(mStates[mStateIndex]); } @Override protected int[] onCreateDrawableState(int extraSpace) { final int[] drawableState = super.onCreateDrawableState(extraSpace+1); int [] state = { mStates[mStateIndex] }; mergeDrawableStates(drawableState, state); return drawableState; } public void setOnStateChangedListener(OnStateChangedListener l) { this.mListener = l; } } 的背景

Button

<com.example.statebuttontest.StateButton android:id="@+id/stateButton1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:background="@drawable/statebutton_selector" android:text="" /> (使用监听器)的示例:

Activity