2015-04-08 5 views
0

Я пытаюсь реализовать пользовательское выведенное состояние. Я вижу состояние, изменяющееся внутри моего пользовательского представления, но визуально нет изменения цвета. Любая помощь ценится!Пользовательское пользовательское выведенное состояние не работает

Вот мой код:

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

Selector состояние должно быть либо истинным, либо ложным. 'app: my_state =" 1 "и' app: my_state = "2" 'оба разрешают' app: my_state = "true" '. Кроме того, селектора должны быть заказаны от наиболее специфичных до наименее специфичных. Ваш первый элемент селектора соответствует всем возможным состояниям. – alanv

+0

спасибо, что решил! сделайте этот комментарий ответом, чтобы я мог его выбрать. Не могу поверить, что я потратил час на это. – vkislicins

ответ

2

Выберите или состояния должны быть определены как атрибуты boolean. Вы можете разместить их непосредственно внутри элемента <resources> - вам не нужно размещать их внутри элемента <styleable>.

разреша/attrs.xml:

<resources> 
    ... 
    <attr name="state_mystate" format="boolean" /> 
</resources> 

При ссылке на атрибут из селектора <item>, значение true означает, что состояние должно существовать в пределах текущего состояния, установленном в то время как значение false означает, что состояние должно нет есть. Если вы не включаете состояние на <item>, не имеет значения, существует ли он в текущем состоянии.

Когда согласование выполняется на селекторе, элементы сопоставляются в том порядке, в котором они определены. Если первый элемент не имеет определенных состояний, как в вашем примере, он будет соответствовать всем возможным состояниям и всегда будет соответствовать первым. В результате вы должны заказать свои элементы селектора как наиболее специфичные для наименее специфичных.

Приведенный ниже пример предназначен для рисования, но применим ко всем селекторам (цвет и т. Д.).

Рез/рисуют/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> 
Смежные вопросы