これは簡単に見えますが、ImageButton
を無効にすることはできません。引き続きクリックイベントを受け取り、その外観は標準のボタンのように変化しません。
SOにはいくつかの 同様の質問 がありますが、それらは私を助けません。
このような非常にシンプルなレイアウトでも:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical">
<ImageButton
Android:id="@+id/btn_call"
Android:layout_height="wrap_content"
Android:layout_width="wrap_content"
Android:clickable="false"
Android:enabled="false"
Android:src="@Android:drawable/sym_action_call" />
</LinearLayout>
ボタンはまだ有効で、クリックできます。
奇妙なのは、ImageButton
を単純なButton
に変更すると、期待どおりに機能することです。ボタンは無効になり、クリックできなくなります。わかりません。誰かがアイデアを持っていますか?
ImageButton
には異なる継承チェーンがあり、Button
を拡張しません。
ImageButton
<ImageView
<View
引き続きクリックイベントを受け取ります
View
のクリックリスナーを設定すると、次のようになります。
_public void setOnClickListener(OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
mOnClickListener = l;
}
_
したがって、リスナーを設定すると、_Android:clickable="false"
_は_Android:clickable="true"
_に変更されます。
そしてその外観は標準のボタンのように変化しません
_Android:enabled
_に基づいて適切な画像を設定できるように、ビューに描画可能な状態リストを提供する必要があります。これありませんか?または、ボタンの唯一の画像がありますか?
編集:StateListDrawable here に関する情報を見つけることができます。 _Android:state_enabled
_は、その状態に使用するイメージをOSに指示するためにリストで使用する必要があるものです。
EDIT2:本当にリスナーを追加する必要があるので、リスナー内でチェックを行うことができますif (!isEnabled()) { return; } else { /* process the event */ }
。
ImageButton
を無効にしてグレー表示にするには、次のコードを使用します。
_/**
* Sets the specified image buttonto the given state, while modifying or
* "graying-out" the icon as well
*
* @param enabled The state of the menu item
* @param item The menu item to modify
* @param iconResId The icon ID
*/
public static void setImageButtonEnabled(Context ctxt, boolean enabled, ImageButton item,
int iconResId) {
item.setEnabled(enabled);
Drawable originalIcon = ctxt.getResources().getDrawable(iconResId);
Drawable icon = enabled ? originalIcon : convertDrawableToGrayScale(originalIcon);
item.setImageDrawable(icon);
}
/**
* Mutates and applies a filter that converts the given drawable to a Gray
* image. This method may be used to simulate the color of disable icons in
* Honeycomb's ActionBar.
*
* @return a mutated version of the given drawable with a color filter
* applied.
*/
public static Drawable convertDrawableToGrayScale(Drawable drawable) {
if (drawable == null) {
return null;
}
Drawable res = drawable.mutate();
res.setColorFilter(Color.GRAY, Mode.SRC_IN);
return res;
}
_
単にsetImageButtonEnabled()
を呼び出します。唯一の欠点は、変換されたアイコンを元に戻すことができないため、ここに画像のリソースIDが必要なことです。
ビュー階層に同じIDのビューがないことを確認し、そのビューにクリックリスナーを追加しないでください。
画像ボタンを無効にする場合は、クリックイベントで、プロパティ「setEnabled」をfalseに設定します。
例:imgButton.setEnabled(false);
Oleg Vaskevich の答えを利用する。 Kotlinの答えになります。
ImageButtonの 拡張機能 を次のように作成します。
/**
* Sets the specified image buttonto the given state, while modifying or
* "graying-out" the icon as well
*
* @param enabled The state of the menu item
* @param iconResId The icon ID
*/
fun ImageButton.setButtonEnabled(enabled: Boolean, iconResId: Int) {
isEnabled = enabled
val originalIcon = context.resources.getDrawable(iconResId)
val icon = if (enabled) originalIcon else convertDrawableToGrayScale(originalIcon)
setImageDrawable(icon)
}
また、Contextの提供への依存度がやや低くなります。
私はなんとかOleg Vaskevichの answer に触発されたソリューションを構築できましたが、描画可能リソースIDをsetEnabled()に渡す必要はありませんでした。
次に、ユーティリティモジュール内のKotlinコードを示します。
fun Drawable.deepCopy(): Drawable =
constantState?.newDrawable()?.mutate() ?:
throw RuntimeException("Called on null Drawable!")
fun Drawable.toGrayscale(): Drawable =
deepCopy().apply { setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN) }
fun ImageButton.setAndShowEnabled(enabled: Boolean) {
if (enabled == isEnabled)
return
isEnabled = enabled
if (enabled) {
setImageDrawable(tag as Drawable)
}
else {
if (tag == null)
tag = drawable
setImageDrawable(drawable.toGrayscale())
}
}
次のように使用できます。
val button: ImageButton = findViewById(...)
// ...
button.setAndShowEnabled(false)
// launch async operation
GlobalScope.launch {
// do work here
// unblock button
button.setAndShowEnabled(true)
}
他の回答が述べたように、ImageButton
のようにレイアウトXMLでButton
を無効にすることはできませんが、実行時に同じ方法で両方を無効にすることができます。
Javaの場合:
_button.setEnabled(false); // setEnabled(boolean) on TextView
imgButton.setEnabled(false); // setEnabled(boolean) on View
_
どちらの場合も、ボタンは無効になっています。クリックイベントはonClickListener
に到達しません。
アイコンが着色可能であると仮定して、無効にされたImageButton
のテキストの色を変更するのと同じ方法で、無効にされたButton
のアイコンの色を変更することもできます。
レイアウトXMLでは:
_<Button
...
Android:textColor="@drawable/button_color_selector" />
<ImageButton
...
Android:tint="@drawable/button_color_selector" />
_
Button
またはImageButton
のsetEnable(boolean)
は、_button_color_selector.xml
_の状態に応じてテキストまたはアイコンの色を変更します