android - 如何使用自定义选择器状态实现 CustomView?

标签 android android-custom-view android-selector

我想创建一个显示图像的 CustomView。单击 View 应更改其状态。 View 可以表示三种状态(off, set, notset)。我想用 XML 格式的 选择器 来做到这一点。它不一定是自定义选择器。我可以重用选择器的三种状态(那时状态名称是否不同并不重要)。

有什么好的方法可以实现吗?

最佳答案

以防万一您的问题尚未自行解决。我通过 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”这样的可绘制对象只是代表各个状态的 .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 文件中引用您正确的包名称,如您的 list 文件中所述:

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

最后,StateButton 类扩展了 Button。使用一个简单的 OnClickListener 状态就会改变。我还实现了一个 OnStateChangedListener,例如,它可以由包含 Button 的 Activity 实现,并在状态发生变化时被调用。

状态本身的更改是在 onCreateDrawableState(...) 方法内完成的,每次单击 Button 时都会自动调用该方法。 “extraspace + 1”表示 drawableStates 数组中将多一个状态。

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 示例(带监听器):

public class MainActivity extends Activity implements OnStateChangedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        StateButton s = (StateButton) findViewById(R.id.stateButton1);
        s.setOnStateChangedListener(this);
    }

    @Override
    public void onStateChanged(int state) {
        Log.i("Main", "State changed to: " + getResources().getResourceEntryName(state));
    }
}

关于android - 如何使用自定义选择器状态实现 CustomView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21930562/

相关文章:

android - 如何从自定义 View 访问宿主 fragment 的生命周期范围?

android - 如何更改可扩展 ListView 项目的背景

android - 在 ListView 中启用选择

android - 如何在Android中的Couchbase-lite中实现 "WHERE"条件

android - onLeScan 在发现蓝牙文件设备时调用了两次

javascript - 如何在 Android 上的 Cordova Chrome 应用程序中播放字符串中的 Base64 编码的 mp3?

android - 如何在Android中水平实现弯曲的自定义按钮?

android - 单击打开上下文菜单

java - 自定义线性布局在添加 View 时有问题

android - 如何处理对 listView 行的点击,同时可能会调用 notifyDataSetChanged?