2014-02-21 57 views
7

我想创建一个CustomView显示图像。点击视图应该改变它的状态。应该有三种状态(关闭,设置,未设置)该视图可以表示。我想用XML编写一个选择器。它并不需要成为自定义选择器。我可以重用选择器的三种状态(如果状态的名称不同,那么无关紧要)。如何使用自定义选择器状态实现CustomView?

是否有实现这一目标的好方法?

回答

13

万一您的问题并没有解决自己呢。我使用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> 

和选择(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文件,在你的清单文件中指出:

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

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

状态本身的更改是在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)); 
    } 
} 
相关问题