CustomView
画像を表示するを作成したい。クリックすると、ビューの状態が変わります。ビューが表すことができる 3 つの状態(オフ、設定、未設定)が必要です。XMLのセレクターでこれを行いたいです。必ずしもカスタム セレクターである必要はありません。セレクターの 3 つの状態を再利用できます (状態の名前が異なっていてもかまいません)。
これを達成する良い方法はありますか?
CustomView
画像を表示するを作成したい。クリックすると、ビューの状態が変わります。ビューが表すことができる 3 つの状態(オフ、設定、未設定)が必要です。XMLのセレクターでこれを行いたいです。必ずしもカスタム セレクターである必要はありません。セレクターの 3 つの状態を再利用できます (状態の名前が異なっていてもかまいません)。
これを達成する良い方法はありますか?
問題がまだ解決していない場合に備えて。Android の新しい実装で状態の変更を行いますButton
。
状態は .xml で定義され、セレクターを介して設定されます。次に、 attrs.xmlファイルで定義された 3 つの状態を示します。
<?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
、たとえば、ボタンを含むアクティビティによって実装でき、状態が変化するたびに呼び出される も実装しました。
状態自体の変更は、ボタンがクリックされるたびに自動的onCreateDrawableState(...)
に呼び出されるメソッド内で行われます。「余分なスペース + 1」は、drawableStates 配列内に 1 つの追加の状態があることを意味します。
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));
}
}