web-dev-qa-db-ja.com

Android、ボタンの背景色を設定すると波及効果が失われる

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>
20
Tommy Saechao

追加のリップルドローアブルを使用して、リップル効果と背景色を追加できます。

あなたのレイアウト:

<?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>
28
Bertrand Martel

これを行う非常にシンプルで簡単な方法は、?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"/>
26
Abhishek Bansal

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>

ボタンの背景を変更する必要はありません。

完全にカスタムの背景が必要な場合は、セレクタを作成する必要があります。そして、そこにリップル効果を設定できます。

14
thealeksandr

使用するだけ:

Android:backgroundTint="#4CAF50"

の代わりに:

Android:background="#4CAF50"

ButtonAndroid.support.v7.widget.AppCompatButtonに変更することを忘れないでください

4
Gilad Shapira

実際には、ドロウアブルの_<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内でクリック可能なビューを囲む余分なオーバーヘッドなどの問題がないため、この方法が好まれます。

0
apc