我正在尝试实现自定义可绘制状态。我可以在自定义视图中看到状态发生变化,但是在视觉上没有颜色变化。任何帮助表示赞赏!
这是我的代码:
selector.xml
<?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.test.myapplication">
<item android:drawable="@drawable/defaultt" />
<item android:drawable="@drawable/error" app:my_state="1" />
<item android:drawable="@drawable/success" app:my_state="2" />
</selector>
error.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape
android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="3dip" />
<stroke android:width="3dip" android:color="#ff0000" />
<solid android:color="#ff0000"/>
</shape>
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyState">
<attr name="my_state" format="integer" />
</declare-styleable>
</resources>
activity_main.xml中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.example.test.myapplication.CustomView
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector"
/>
</LinearLayout>
CustomView.java
public class CustomView extends View {
public static final int DEFAULT = 0;
public static final int ERROR = 1;
public static final int SUCCESS = 2;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
private int state = DEFAULT;
private static final int[] VALIDATION_STATE = new int[] { R.attr.my_state };
@Override
protected int[] onCreateDrawableState(int extraSpace) {
if( state == DEFAULT ) {
return super.onCreateDrawableState(extraSpace);
}
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (state > 0) {
Log.d("tag", "state is "+state);
mergeDrawableStates(drawableState, VALIDATION_STATE);
}
return drawableState;
}
public void setState(int state) {
this.state = state;
refreshDrawableState();
}
}
MainActivity.java
public class MainActivity extends ActionBarActivity {
private int mCurrentState = CustomView.DEFAULT;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentState != CustomView.ERROR) {
((CustomView) findViewById(R.id.view)).setState(CustomView.ERROR);
mCurrentState = CustomView.ERROR;
} else {
((CustomView) findViewById(R.id.view)).setState(CustomView.SUCCESS);
mCurrentState = CustomView.SUCCESS;
}
}
});
}
}
答案 0 :(得分:3)
选择器状态应定义为boolean
属性。您可以将它们直接放在<resources>
元素中 - 您无需将它们放在<styleable>
元素中。
RES / attrs.xml:
<resources>
...
<attr name="state_mystate" format="boolean" />
</resources>
当您从选择器<item>
引用属性时,值true
表示状态必须存在于当前状态集中,而值false
表示状态必须不存在。如果您在<item>
上没有包含状态,那么它是否存在于当前状态集中无关紧要。
在选择器上执行匹配时,项目按照定义的顺序进行匹配。如果第一个项目没有定义状态,就像在您的示例中那样,它将匹配所有可能的状态并始终首先匹配。因此,您应该将选择器项目排序为最具体到最不具体的。
以下示例适用于drawable,但它适用于所有选择器(颜色等)。
RES /抽拉/ my_selector.xml:
<selector>
<!-- Matches only state sets that include app:state_mystate
and don't include android:state_pressed. -->
<item app:state_mystate="true"
android:state_pressed="false" ... />
<!-- Matches all state sets that include state_mystate. -->
<item app:state_mystate="true" ... />
<!-- Matches all possible states. -->
<item ... />
</selector>