Android自定义可绘制状态不起作用

时间:2015-04-08 20:38:26

标签: android

我正在尝试实现自定义可绘制状态。我可以在自定义视图中看到状态发生变化,但是在视觉上没有颜色变化。任何帮助表示赞赏!

这是我的代码:

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;
                }
            }
        });
    }
}

1 个答案:

答案 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>