我想创建一个CustomView
显示图像的。单击时,视图应更改其状态。视图可以表示三种状态(关闭、设置、未设置) 。我想用XML 中的选择器来做到这一点。它不一定需要是自定义选择器。我可以重用选择器的三种状态(然后状态的名称是否不同并不重要)。
有没有好的方法来实现这一目标?
我想创建一个CustomView
显示图像的。单击时,视图应更改其状态。视图可以表示三种状态(关闭、设置、未设置) 。我想用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”这样的drawables只是代表各个状态的.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
扩展类Button
。用一个简单OnClickListener
的状态改变。我还实现了一个OnStateChangedListener
,例如可以由一个包含 Button 的 Activity 实现,并且在状态更改时将被调用。
状态本身的更改是在每次单击 Button 时自动onCreateDrawableState(...)
调用的方法内部完成的。"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));
}
}