[解決済み] カスタムボタンの状態を追加する方法
質問
例えば、デフォルトのボタンは、その状態と背景画像との間に以下のような依存関係があります。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
独自の状態を定義するにはどうすればよいのでしょうか (たとえば
android:state_custom
のような)独自の状態を定義し、それを使ってボタンの外観を動的に変更することはできますか?
どのように解決するのですか?
(Ted Hopp) によって示された解決策は機能しますが、少し修正が必要です。セレクタにおいて、項目の状態には "app:" というプレフィックスが必要で、さもなければインフレータは名前空間を正しく認識できず、静かに失敗します。少なくとも、これは私に起こったことです。
もう少し詳しく、解決策全体をここで報告することを許可してください。
まず、ファイル "res/values/attrs.xml" を作成します。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="food">
<attr name="state_fried" format="boolean" />
<attr name="state_baked" format="boolean" />
</declare-styleable>
</resources>
次に、カスタムクラスを定義します。例えば、Buttonクラスから派生して、FoodButtonクラスとします。コンストラクタを実装する必要がありますが、これはインフレータが使用するものと思われますので、これを実装してください。
public FoodButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
派生クラスの上に
private static final int[] STATE_FRIED = {R.attr.state_fried};
private static final int[] STATE_BAKED = {R.attr.state_baked};
また、状態変数も
private boolean mIsFried = false;
private boolean mIsBaked = false;
そして、いくつかのセッター。
public void setFried(boolean isFried) {mIsFried = isFried;}
public void setBaked(boolean isBaked) {mIsBaked = isBaked;}
次に、関数 "onCreateDrawableState"をオーバーライドします。
@Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 2);
if (mIsFried) {
mergeDrawableStates(drawableState, STATE_FRIED);
}
if (mIsBaked) {
mergeDrawableStates(drawableState, STATE_BAKED);
}
return drawableState;
}
最後に、このパズルの最も繊細な部分です。ウィジェットの背景として使用する StateListDrawable を定義するセレクタです。これは、ファイル "res/drawable/food_button.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.mydomain.mypackage">
<item
app:state_baked="true"
app:state_fried="false"
android:drawable="@drawable/item_baked" />
<item
app:state_baked="false"
app:state_fried="true"
android:drawable="@drawable/item_fried" />
<item
app:state_baked="true"
app:state_fried="true"
android:drawable="@drawable/item_overcooked" />
<item
app:state_baked="false"
app:state_fried="false"
android:drawable="@drawable/item_raw" />
</selector>
標準的なアンドロイドの状態では、プレフィックス "android:" を使用していたのに対し、"app:" に注意してください。XML名前空間は、インフレータが正しく解釈するために重要であり、属性を追加するプロジェクトの種類に依存します。アプリケーションの場合は com.mydomain.mypackage をアプリケーションの実際のパッケージ名に置き換えてください(アプリケーション名は除く)。ライブラリの場合は、"http://schemas.android.com/apk/res-auto" を使用する必要があります (また、Tools R17 以降を使用していること)。さもなければ、ランタイム エラーが発生します。
2、3 の注意事項。
-
quot;refreshDrawableState" 関数を呼び出す必要はないようで、少なくとも私の場合、解決策はそのままでうまく動作します。
-
レイアウト xml ファイルでカスタム クラスを使用するには、完全修飾名 (例: com.mydomain.mypackage.FoodButton) を指定する必要があります。
-
より複雑な状態の組み合わせを表現するために、標準の状態(例:android:pressed, android:enabled, android:selected) とカスタム状態を混在させることができます。
関連
-
IllegalStateException。ArrayAdapter は、リソース ID が TextView である必要があります。
-
ConstraintLayoutのいくつかのプロパティの概要(RelativeLayoutの強化版、LinearLayoutの比例プロパティを含む、階層ツールの削減)。
-
問題 ---- Android ---- ActivityManager: Error: アクティビティクラス{xx/xx.MainActivity}が存在しない
-
Androidの美しいSeekBarスタイルのカスタマイズ
-
[解決済み] android.os.NetworkOnMainThreadException' を修正するにはどうすればよいですか?
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] Androidでアクティビティ起動時にEditTextにフォーカスが当たらないようにする方法
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み] リンクのように動作するHTMLボタンを作成する方法
-
[解決済み] Chromeデベロッパーツールで:hoverの状態を見る
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
adb シェルがデバイスのオフラインを求めるプロンプトを表示する
-
AndroidがMainActivityが包含クラスでないというエラーを報告する
-
Androidで発生した問題、解決策とヒント
-
ActivityはOnFragmentInteractionListenerを実装しなければならないに関する質問
-
エラー:未宣言の識別子(AS)の使用
-
repo: コマンドが見つかりません
-
Androidで、onTouchEventでダブルクリックを実装し、ダブルクリックイベントとして判定する方法
-
Android ProgressBarの色を変更する
-
Androidの美しいSeekBarスタイルのカスタマイズ
-
SpinnerのOnItemSelectedListenerのonItemSelectedメソッドの4つのパラメーターの意味