Androidボタンに色を追加すると、波及効果が失われるため、ユーザーは応答性の高いクリックがあるように感じます。これを修正するにはどうすればよいですか?多くのソリューションを検索しましたが、できませんでしたあいまいではない明確なものを見つけないでください。
<RelativeLayout 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"
tools:context=".ClockInOutFragment">
<AnalogClock
Android:id="@+id/clock"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentEnd="true"
Android:layout_alignParentRight="true"
Android:layout_alignParentTop="true"
Android:layout_toRightOf="@+id/date_and_time"/>
<RelativeLayout
Android:id="@+id/date_and_time"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_margin="10dp">
<TextView
Android:id="@+id/time_digits"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="12:10"
Android:textSize="45sp"/>
<TextView
Android:id="@+id/am_pm"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignBaseline="@+id/time_digits"
Android:layout_toRightOf="@+id/time_digits"
Android:paddingLeft="3dp"
Android:text="PM"
Android:textSize="20sp"/>
<TextView
Android:id="@+id/date"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@+id/time_digits"
Android:text="Mon, July 11"
Android:textSize="22sp"/>
</RelativeLayout>
<!--Clock in and out buttons-->
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_alignParentBottom="true"
Android:layout_centerHorizontal="true"
Android:orientation="horizontal">
<Button
Android:id="@+id/textView3"
Android:layout_width="0dp"
Android:layout_height="56dp"
Android:layout_weight="1"
Android:background="#4CAF50"
Android:gravity="center"
Android:text="Clock In"
Android:textAppearance="?android:attr/textAppearanceLarge"
Android:textColor="#FFFFFF"/>
<!--Divider between the clock in and out button-->
<View
Android:layout_width="1dp"
Android:layout_height="match_parent"
Android:background="#B6B6B6"/>
<Button
Android:id="@+id/textView4"
Android:layout_width="0dp"
Android:layout_height="56dp"
Android:layout_weight="1"
Android:background="#FF5252"
Android:gravity="center"
Android:text="Clock Out"
Android:textAppearance="?android:attr/textAppearanceLarge"
Android:textColor="#FFFFFF"/>
</LinearLayout>
</RelativeLayout>
追加のリップルドローアブルを使用して、リップル効果と背景色を追加できます。
あなたのレイアウト:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Button
Android:id="@+id/button_connect"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_marginTop="20dip"
Android:fontFamily="sans-serif"
Android:text="Connect"
Android:background="@drawable/ripple"
Android:textColor="#FFFFFF"
Android:textSize="18sp" />
</LinearLayout>
ripple.xml(リップル効果に加えて背景色を追加できる場所):
<?xml version="1.0" encoding="utf-8"?>
<!-- in drawable folder-->
<ripple
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:color="?android:colorControlHighlight">
<item Android:id="@Android:id/mask">
<shape Android:shape="rectangle">
<solid Android:color="?android:colorAccent" />
</shape>
</item>
<item>
<shape Android:shape="rectangle">
<!-- put your background color here-->
<solid Android:color="@color/default_color" />
</shape>
</item>
</ripple>
これを行う非常にシンプルで簡単な方法は、?attr/selectableItemBackground
からAndroid:foreground
ボタンの属性。次のXMLは完全に有効であり、動作します
<Button
Android:id="@+id/btn"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@Android:color/white"
Android:foreground="?attr/selectableItemBackground"/>
Buttonの背景を変更しないでください。テーマを変更します。
<style name="ButtonGray">
<item name="colorButtonNormal">@color/gray</item>
</style>
そしてあなたのxmlファイルで
<Button
Android:id="@+id/accept_button"
Android:layout_height="wrap_content"
Android:layout_width="0dp"
Android:layout_weight="1"
Android:text="@string/button_accept_group"
Android:theme="@style/ButtonGray"/>
または、メインアプリのテーマに追加できます
<style name="AppTheme"
parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorButtonNormal">@color/primary_color</item>
</style>
ボタンの背景を変更する必要はありません。
完全にカスタムの背景が必要な場合は、セレクタを作成する必要があります。そして、そこにリップル効果を設定できます。
使用するだけ:
Android:backgroundTint="#4CAF50"
の代わりに:
Android:background="#4CAF50"
Button
をAndroid.support.v7.widget.AppCompatButton
に変更することを忘れないでください
実際には、ドロウアブルの_<layer-list>
_を使用して、波及効果を他のドロウアブルと組み合わせることができます。これはpre-lolipopの普遍的なソリューションでもあります。多くの構成でテストしました。
唯一の問題は、_?selectableItemBackground
_が_<layer-list>
_内にあるときにpre-lolipopがクラッシュするため、プログラムでLayerDrawableを作成する必要があることです。
非常に高速でシンプルなソリューションは次のようになります。
ビューに指定する
_Android:background="?selectableItemBackground"
_
次に、コードの任意の場所でmySpecialDrawableを作成し、トリックを実行します。
_Drawable[] layers = {mySpecialDrawable, getBackground()};
setBackgroundDrawable(new LayerDrawable(layers).mutate());
_
ここでLayeredDrawableの.mutate()
は必須であることに注意してください!
より複雑なソリューションは、カスタムビューが既にあり、親として余分な空のFrameLayoutを追加するよりも、その機能と互換性を拡張したい場合に便利です。
Attrs.xmlの内部:
_<resources>
<declare-styleable name="MyView">
<attr name="selectableBackground" format="reference"/>
<attr name="backgroundDrawable" format="reference"/>
</declare-styleable>
</resources>
_
次に、View-descendantクラス内で:
_private Drawable selectableBackground;
private Drawable backgroundDrawable;
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
try {
TypedArray attributeArray;
attributeArray = context.obtainStyledAttributes(attrs, R.styleable.MyView);
int id = attributeArray.getResourceId(R.styleable.MyView_selectableBackground, -1);
if (id != -1) {
selectableBackground = ResourcesCompat.getDrawable(getResources(), id, context.getTheme());
}
id = attributeArray.getResourceId(R.styleable.MyView_backgroundDrawable, -1);
if (id != -1) {
backgroundDrawable = ResourcesCompat.getDrawable(getResources(), id, context.getTheme());
}
constructBackground();
attributeArray.recycle();
} catch (Exception e) {
Log.e(this.toString(), "Attributes initialization error", e);
throw e;
}
}
void setSelectableBackground(Drawable drawable) {
selectableBackground = drawable;
constructBackground();
}
void setDrawable(Drawable drawable) {
backgroundDrawable = drawable;
constructBackground();
}
private void constructBackground() {
if (selectableBackground != null) {
if (backgroundDrawable != null) {
Drawable[] layers = {backgroundDrawable, selectableBackground};
setBackgroundDrawable(new LayerDrawable(layers).mutate()); // Both, using layers
} else setBackgroundDrawable(selectableBackground); // Selectable only
} else setBackgroundDrawable(backgroundDrawable); // Background only or null
}
_
このアプローチは、_Android:foreground
_属性(23+以上)またはFrameLayout内でクリック可能なビューを囲む余分なオーバーヘッドなどの問題がないため、この方法が好まれます。