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!

Rakcode
quelle
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" />
Pei
quelle
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".

backslashN
quelle
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" />
Jigar Patel
quelle
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"
Sudheesh R.
quelle
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/

Jasmine John
quelle
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
}
Gibolt
quelle
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" />
Ashwin
quelle
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>
Digvijay Machale
quelle
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>
Atman Bhatt
quelle
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" />
Raveendra
quelle
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>
Adam Hurwitz
quelle
3

Benutz einfach :

android:backgroundTint="#f816a463"

Anstatt:

android:background="#f816a463"

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

Gilad Shapira
quelle
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>
Aidan Host
quelle
Warum sollte backgroundResource programmgesteuert erneut festgelegt werden, während layout xml den Hintergrund von Button definiert?
SunnyShiny9