Fügen Sie meiner Schaltfläche einen Welleneffekt mit Hintergrundfarbe hinzu?


124

Ich habe eine Schaltfläche erstellt und möchte dieser Schaltfläche einen Welleneffekt hinzufügen!

Ich habe eine Schaltfläche bg XML-Datei erstellt: (bg_btn.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFF" android:endColor="#00FF00" android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>

Und das ist meine Ripple-Effekt-Datei: (ripple_bg.xml)

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

Und dies ist mein Button, den ich mit einem Welleneffekt versehen möchte:

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:layout_centerHorizontal="true"
android:layout_marginTop="173dp"
android:textColor="#fff"
android:background="@drawable/ripple_bg"
android:clickable="true" />

Nach dem Hinzufügen des Ripple-Effekts ist der Hintergrund der Schaltfläche transparent und die Schaltfläche wird nur angezeigt, wenn Sie darauf klicken:

Vor dem Klicken

On Click

Aber ich brauche sowohl die Hintergrundfarbe der Schaltfläche als auch den Welleneffekt. Ich habe einen Teil dieses Codes in verschiedenen Blogs von Stack Overflow gefunden, aber es funktioniert immer noch nicht!


Bitte machen Sie Screenshots beim nächsten Mal viel kleiner. (Größe vor dem Hochladen ändern)
user25

@ user25, Sie können auch einfach ein loder mzum Bildlink hinzufügen . (siehe meine Bearbeitung)
Suragch

Antworten:


153

Hier ist eine weitere zeichnbare XML für diejenigen, die den Verlaufshintergrund, den Eckenradius und den Welligkeitseffekt addieren möchten:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDark">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorPrimaryLight"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>
</ripple>

Fügen Sie dies zum Hintergrund Ihrer Schaltfläche hinzu.

<Button
    ...
    android:background="@drawable/button_background" />

4
@pei Wie bekommt ihr diese Infos? Ich meine, woher weißt du, dass es ein XML-Element namens Ripple gibt, um diesen Job zu erledigen?

1
Dies ist eines der Konzepte, die im Materialdesign verwendet werden. Bitte fangen Sie an, ein neues Root-Tag in eine zeichnbare XML in Android Studio einzugeben. Dann sollten Sie alle verfügbaren Tags einschließlich sehen können ripple.
Pei

1
Was ist die Verwendung von Maskenelementen?
Prashant

10
Dies erfordert API Level 21
M. Kazem Akhgary 16.

2
es funktioniert, aber wie es funktioniert, wird nicht erklärt. Es sollte mit der ID des Elements verknüpft sein. Sollte referenziert werden.
Oiyio

155

Fügen "?attr/selectableItemBackground"Sie das android:foregroundAttribut Ihrer Ansicht hinzu , wenn es bereits einen Hintergrund zusammen mit hat android:clickable="true".


funktioniert nicht immer, aber Sie können dem Welleneffekt einen Hintergrund hinzufügen, wie in den Kommentaren der akzeptierten Antwort angegeben
Tyler

Ich musste diese Lösung verwenden, da ich einen benutzerdefinierten Hintergrund für meine Schaltfläche verwendet habe. Es hat super funktioniert.
Bnayagrawal

@ROAR, das stimmt, aber zumindest: "Dies ist kein Fehler. Die Anwendung ignoriert das Attribut einfach. Wenn das Attribut jedoch für das Erscheinungsbild oder die Funktionalität Ihrer Anwendung wichtig ist, sollten Sie einen alternativen Weg finden, um dies zu erreichen." Das gleiche Ergebnis mit nur verfügbaren Attributen. Anschließend können Sie optional eine Kopie des Layouts in einem Layout-vNN-Ordner erstellen, der auf API NN oder höher verwendet wird, wo Sie das neuere Attribut nutzen können. " So funktioniert es gut auf Geräten über API 23 und wird ignoriert, wenn unten (wir können nur tools:ignore="UnusedAttribute).
JorgeAmVF

Ohne Android-Support-Bibliothek wäre es ?android:attr/selectableItemBackground( android:attranstelle von attr)
Wochenende

1
android:foregroundAttribut hat keine Auswirkung auf API-Level unter 23
Vadim Kotov

67

Fügen Sie einem Android-Button Ripple-Effekt / Animation hinzu

Ersetzen Sie einfach Ihr Button-Hintergrundattribut durch android: background = "? Attr / selectableItemBackground" und Ihr Code sieht so aus.

      <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/selectableItemBackground"
        android:text="New Button" />

Eine andere Möglichkeit, einem Android-Button Ripple-Effekt / Animation hinzuzufügen

Mit dieser Methode können Sie die Farbe des Welleneffekts anpassen. Zuerst müssen Sie eine XML-Datei in Ihrem Zeichenressourcenverzeichnis erstellen. Erstellen Sie eine Datei ripple_effect.xml und fügen Sie den folgenden Code hinzu. res / drawable / ripple_effect.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

Und setzen Sie den Hintergrund der Schaltfläche auf die obige Zeichnungsressourcendatei

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/ripple_effect"
    android:padding="16dp"
    android:text="New Button" />

1
Für mich trat kein Welleneffekt auf. Es war nur ein Farbschalter für die Schaltfläche: / Meine Android-Version ist 5.1.1, also sollte es funktionieren. Könntest du helfen? Ich folgte Ihren Schritten
UrviG

android: Farbe sollte sich vom Mast unterscheiden android: color, oder Sie möchten den
Welleneffekt

2
Wenn Sie einen Hintergrund wünschen, fügen Sie der Welligkeit einfach ein weiteres Element hinzu, z. B.: <item android: drawable = "? attr / colorPrimary" />
Tyler

36

Fügen Sie diese zusätzlich zur Lösung von Jigar Patel zur Datei ripple.xml hinzu , um einen transparenten Hintergrund der Schaltflächen zu vermeiden.

<item
    android:id="@android:id/background"
    android:drawable="@color/your-color" />

Komplette XML :

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/your-color"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/your-color" />
        </shape>
    </item>
    <item
        android:id="@android:id/background"
        android:drawable="@color/your-color" />
</ripple>

Verwenden Sie diese ripple.xml als Hintergrund für Ihre Schaltfläche:

android:background="@drawable/ripple"

2
Wir mussten das nicht benutzen <item android:id="@android:id/mask"> [...]. Es sei denn, Sie möchten eine ovale Maske. Danke für deine Antwort!
Filipe Brito

Was macht dieses <item android: id = "@ android: id / mask"> überhaupt? Ich habe 2 ähnliche Elemente mit und ohne dieses Attribut erstellt und sie sehen genauso aus
Sartheris Stormhammer

@SartherisStormhammer aus offiziellen Dokumenten: Wenn eine Maskenebene festgelegt ist, wird der Welligkeitseffekt gegen diese Ebene maskiert, bevor er über den Verbund der verbleibenden untergeordneten Ebenen gezogen wird. Wenn keine Maskenebene festgelegt ist, wird der Welligkeitseffekt gegen den Verbund der untergeordneten Ebenen maskiert. Dies ist der Link, developer.android.com/reference/android/graphics/drawable/…
Sudheesh R

@ SudheeshR, das macht es nur verwirrender
Sartheris Stormhammer

@SartherisStormhammer Aus dieser offiziellen Dokumentation ist es ziemlich klar, denke ich. Der Welleneffekt wird über untergeordnete / maskierte Ebenen gezogen. Bitte lesen Sie das Dokument noch einmal, Sie werden es verstehen.
Sudheesh R

32

Wenn die Schaltfläche einen Hintergrund aus dem Zeichen hat, können wir dem Vordergrundparameter einen Welleneffekt hinzufügen. Überprüfen Sie den folgenden Code, ob er für meine Schaltfläche mit einem anderen Hintergrund funktioniert

    <Button
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:gravity="center"
    android:layout_centerHorizontal="true"                                                             
    android:background="@drawable/shape_login_button"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:text="@string/action_button_login"
     />

Fügen Sie den folgenden Parameter für den Welligkeitseffekt hinzu

   android:foreground="?attr/selectableItemBackgroundBorderless"
   android:clickable="true"

Als Referenz siehe unten Link https://jascode.wordpress.com/2017/11/11/how-to-add-ripple-effect-to-an-android-app/


2
Attribut android: Vordergrund hat keine Auswirkung auf API-Level unter 23
Ali Khaki

Ein Nachteil dieses Ansatzes ist, dass sich die Welligkeit bis zu den rechteckigen Kanten ausbreitete, obwohl mein Tastenhintergrund oval war.
iCantC

13

AppCompat v7 +

Wenn Sie ?android:Ihrer App kein Präfix hinzufügen, stürzt sie ab.

Sie sollten "?android:attr/selectableItemBackground"oder verwenden "?android:attr/selectableItemBackgroundBorderless", je nach Ihren Vorlieben. Ich bevorzuge Borderless.

Sie können es entweder in android:backgroundoder android:foregroundum vorhandene Eigenschaften beizubehalten.

Das Element muss android:clickable="true"und android:focusable="true"um dafür zu arbeiten, aber viele Elemente, wie Knöpfe, haben sie truestandardmäßig aktiviert .

<Button
    ...
    android:background="@color/white"
    android:foreground="?android:attr/selectableItemBackgroundBorderless"
/>
<TextView
    ...
    android:background="?android:attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:focusable="true"
/>

Programmatisch (Java)

TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
myView.setBackgroundResource(value.resourceId);
myView.setFocusable(true); // If needed for view type

Programmatisch (Kotlin)

val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
myView.setBackgroundResource(value.resourceId)
myView.setFocusable(true) // If needed for view type

Wiederverwendbare Kotlin-Erweiterungsfunktion

myView.ripple()

fun View.ripple(): View {
    val value = TypedValue()
    context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
    setBackgroundResource(value.resourceId)
    isFocusable = true // Required for some view types
    return this
}

7

Das Hinzufügen von Vordergrund- und anklickbaren Attributen hat bei mir funktioniert.

<Button
    ... 
    android:background="@color/your_color"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true" />

6

Neben Sudheesh R.

Fügen Sie einem Android-Button mit einer rechteckigen Buttonform mit Ecke einen Welleneffekt / eine Animation hinzu

Erstellen Sie die XML-Datei res / drawable / your_file_name.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/colorWhite"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="50dp" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorAccent"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="50dp" />
        </shape>
    </item>
</ripple>

4

Wenn Sie android: background verwenden, ersetzen Sie einen Großteil des Stils und des Erscheinungsbilds einer Schaltfläche durch eine leere Farbe.

Update: Ab Version 23.0.0 von AppCompat gibt es ein neues Widget.AppCompat.Button.Ein farbiger Stil, der den colorButtonNormal Ihres Themas für die deaktivierte Farbe und colorAccent für die aktivierte Farbe verwendet.

Auf diese Weise können Sie es direkt über auf Ihre Schaltfläche anwenden

<Button
 ...
style="@style/Widget.AppCompat.Button.Colored" />

Sie können ein Drawable in Ihrem v21-Verzeichnis für Ihren Hintergrund verwenden, z.

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>

Dadurch wird sichergestellt, dass Ihre Hintergrundfarbe "attr / colorPrimary" ist und die Standard-Ripple-Animation mit dem Standard "attr / colorControlHighlight" verwendet wird (das Sie auch in Ihrem Design festlegen können, wenn Sie möchten).

Hinweis: Sie müssen einen benutzerdefinierten Selektor für weniger als v21 erstellen:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primaryPressed"            android:state_pressed="true"/>
<item android:drawable="@color/primaryFocused" android:state_focused="true"/>
<item android:drawable="@color/primary"/>
</selector>

Ich benutze MinSDK Level 21
Rakcode

Es gibt keinen v21 zeichnbaren Ordner, nur einen Ordner, der sich selbst v21 Ordner
Rakcode

Ja, ich habe diese API auch verwendet, wenn ich diese API verwende, nachdem ich auf meine App geklickt habe, stürzt ab
Rakcode

Eigentlich
teste

4

Versuche dies

<Button
            android:id="@+id/btn_location"
            android:layout_width="121dp"
            android:layout_height="38dp"
            android:layout_gravity="center"
            android:layout_marginBottom="24dp"
            android:layout_marginTop="24dp"
            android:foreground="?attr/selectableItemBackgroundBorderless"
            android:clickable="true"
            android:background="@drawable/btn_corner"
            android:gravity="center_vertical|center_horizontal"
            android:paddingLeft="13dp"
            android:paddingRight="13dp"
            android:text="Save"
            android:textColor="@color/color_white" />

4

Ein einfacher Ansatz besteht darin, ein Ansichtsthema wie hier beschrieben festzulegen .

some_view.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="?attr/selectableItemBackgroundBorderless"
   android:focusable="true"
   android:src="@drawable/up_arrow"
   android:theme="@style/SomeButtonTheme"/>

some_style.xml

<style name="SomeButtonTheme" >
   <item name="colorControlHighlight">@color/someColor</item>
</style>

3

Benutz einfach :

android:backgroundTint="#f816a463"

Anstatt:

android:background="#f816a463"

Vergiss nicht, deine Buttonzu ändernandroid.support.v7.widget.AppCompatButton


1
Das Schlimme ist, dass Sie dies nicht tun, wenn Sie eine Schaltfläche benötigen, um den horizontalen Bildschirm zu 100% auszufüllen.
Filipe Brito

1

Eine alternative Lösung zur Verwendung des <ripple>Tags (die ich persönlich lieber nicht mache, da die Farben nicht "Standard" sind) ist die folgende:

Erstellen Sie ein Zeichen für den Schaltflächenhintergrund und fügen Sie es <item android:drawable="?attr/selectableItemBackground">in die ein<layer-list>

Dann (und ich denke, das ist der wichtige Teil) programmgesteuert backgroundResource(R.drawable.custom_button)auf Ihre Schaltflächeninstanz setzen.

Aktivität / Fragment

Button btn_temp = view.findViewById(R.id.btn_temp);
btn_temp.setBackgroundResource(R.drawable.custom_button);

Layout

<Button
    android:id="@+id/btn_temp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/custom_button"
    android:text="Test" />

custom_button.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>
    <item android:drawable="?attr/selectableItemBackground" />
</layer-list>

Warum sollte backgroundResource programmgesteuert erneut festgelegt werden, während layout xml den Hintergrund von Button definiert?
SunnyShiny9
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.