Wie kann man eine Schaltfläche kreisförmig kräuseln, wenn sie angeklickt wird?


121

Hintergrund

Wenn Sie in der Dialer-App von Android nach etwas suchen und auf die Pfeilschaltfläche links neben dem EditText klicken, wird ein kreisförmiger Welleneffekt angezeigt:

Geben Sie hier die Bildbeschreibung ein

Das Problem

Ich habe versucht, es auch zu haben, aber ich habe ein rechteckiges:

    <ImageButton
        android:id="@+id/navButton"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="8dp"
        android:background="?android:attr/selectableItemBackground"
        android:src="@drawable/search_ic_back_arrow"/>

Die Frage

Wie kann ich dafür sorgen, dass die Schaltfläche beim Klicken einen kreisförmigen Welleneffekt hat? Muss ich ein neues Zeichen erstellen oder gibt es dafür einen eingebauten Weg?




1
Erwägen Sie, Ihre ausgewählte Antwort in die Antwort mit den meisten positiven Stimmen zu ändern, da dies das Problem tatsächlich löst
Jeff Barger,

@ JeffBarger Warum? Beide funktionieren gut. Es gibt keinen besseren zwischen ihnen.
Android-Entwickler

Antworten:


17

Wenn Sie bereits ein Hintergrundbild haben, finden Sie hier ein Beispiel für eine Welligkeit, die in der Nähe von selectableItemBackgroundBorderless liegt:

            <ImageButton
                android:id="@+id/btn_show_filter_dialog"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:background="@drawable/ic_filter_state"/>

ic_filter_state.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:state_enabled="true"
        android:drawable="@drawable/state_pressed_ripple"/>
    <item
        android:state_enabled="true"
        android:drawable="@drawable/ic_filter" />
</selector>

state_pressed_ripple.xml: (Deckkraft auf 10% auf weißem Hintergrund eingestellt) 1AFFFFFF

 <?xml version="1.0" encoding="UTF-8"?>    
    <ripple xmlns:android="http://schemas.android.com/apk/res/android">
        <item>
            <shape android:shape="oval">
                <solid android:color="#1AFFFFFF"/>
            </shape>
            <color android:color="#FFF"/>
        </item>
    </ripple>

285

Wenn Sie das AppCompat-Design verwenden, können Sie den Hintergrund der Ansicht wie folgt festlegen:

android:background="?selectableItemBackgroundBorderless"

Dies fügt kreisförmige Welligkeit bei 21 und darüber und quadratischen Hintergrund bei unter 21 hinzu.


Nett. Kann ich die Farbe auch irgendwie einstellen?
Android-Entwickler

4
In API 23 scheint der 'up'-Hintergrund halb so groß zu sein wie selectbleItemBackgroundBorderless
snodnipper

3
Schöne, beste Antwort. ty
Skywalker

1
@androiddeveloper, Farbe kann eingestellt werden, indem colorControlHighlight wie unten in Ihrer styles.xml <item name = "colorControlHighlight"> # F00 </ item>
Bond

3
Wenn Sie es in anderen Layouts verwenden, müssen Sie es möglicherweise auch android:clipChildren="false"in den Layouts verwenden, damit sich die Animation verbreiten kann.
Tanasis

82

Ein weiteres Attribut mit rundem Welleneffekt, speziell für die Aktionsleiste:

android:background="?actionBarItemBackground"

UPD : Die Welligkeitsfarbe kann durch dieses Attribut geändert werden:

<!--somewhere in styles-->
<item name="colorControlHighlight">your_color_here</item>

Beachten Sie jedoch, dass dieses Attribut für alle Standard-Welligkeitseffekte gilt.


Gibt es eine Möglichkeit, es anzupassen? Zum Beispiel die Farbe? Vielleicht etwas in Stilen? Oder noch genauer im View XML Tag selbst?
Android-Entwickler

Ich weiß nicht, heute habe ich dieses Problem gelöst und die obigen Antworten haben nicht so funktioniert, wie ich es brauchte. Ich gehe davon aus, dass die Farbe in Stilen angepasst werden kann, aber definitiv nicht in der Ansicht.
Anrimian

1
Dies ist genau der richtige Effekt, den ich suche. Können Sie übrigens erwähnen, wo sich dieses Attribut befindet? Es scheint nicht dokumentiert zu sein.
Jack Wang

2
Beantwortet die OP-Frage. Sollte als beste Antwort markiert werden. +1
Corbella

2
@ MeysamHadigheh ?ist Abkürzung für?attr/
Musooff

47

Erstellen Sie eine Welligkeit, die als Hintergrund gezeichnet werden kann, und legen Sie sie fest. Etwas wie das.

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/grey_15">
    <item android:id="@android:id/mask">
        <shape android:shape="oval">
            <solid android:color="?android:colorPrimary"/>
        </shape>
        <color android:color="@color/white"/>
    </item>
</ripple>

Es ist etwas in meinem Code. Sie können Ihre Farben verwenden :)
Thomas R.

Wie würde ich den Standard-Selektor verwenden, falls er vor Lollipop läuft? Verwendet es auch die gleichen Farben wie auf dem Dialer?
Android-Entwickler

2
Sie können die Ripple Drawable in Ihren Drawables-v21-Ordner legen. Und für Pre L verwenden Sie einen einfachen Zustand zum Zeichnen. Verwenden Sie denselben Dateinamen und legen Sie ihn im Ordner zum Zeichnen (Standard) ab.
Thomas R.

2
Sie können auch einen Stil erstellen. Erstellen Sie im Ordner values-v21 einen neuen Stil und legen Sie die Welligkeit als Hintergrund fest. Und für Pre L, dh in Ihrem Werteordner styles.xml, setzen Sie als Hintergrund das Attribut "selectableItemBackground" für denselben Stil.
Thomas R.

1
Wenn Sie dieselbe Welligkeitsfarbe wie die anderen in der App verwendeten Standard-Welligkeitseffekte wünschen, verwenden Sie "? Attr / colorControlHighlight" als Farbe.
Alexbchr

26

Fügen Sie diesen Hintergrund einfach Ihrer Ansicht hinzu

android:background=?android:attr/actionBarItemBackground


18

Sie können eine Kreiswelligkeit erstellen, die mit dem android:radiusAttribut in XML gezeichnet werden kann.

Beispiel:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="your_color"
    android:radius="your_radius" />

Achten Sie darauf, dass Sie your_radiuskleiner als Ihre Ansichtsbreite und -höhe sein sollten. Zum Beispiel: Wenn Sie eine Ansicht haben, deren Größe 60dp x 60dp your_radiusnahe sein sollte 30dp(Breite / 2 oder Höhe / 2).

Arbeiten Sie mit Android 5.0 und höher.


3

Wenn Sie allgemeinere XML-Dateien wünschen, habe ich zwei Dateien:

1) btn_ripple_background mit Code:

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

2) ripple_circuler_shape mit Code:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/btn_state_pressed_text_color"
    android:shape="oval">
    <solid android:color="@color/btn_state_pressed_text_color" />
</shape>

endlich die verwendung:android:foreground="@drawable/ripple_btn_background"


1

Versuchen:

android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:foreground="?actionBarItemBackground"

1
Bitte posten Sie nicht nur Code als Antwort, sondern geben Sie eine Erklärung an, was Ihr Code tut und wie er das Problem der Frage löst. Antworten mit einer Erklärung sind im Allgemeinen von höherer Qualität und ziehen eher positive Stimmen an.
Mark Rotteveel

Glatter als das Festlegen von actionBarItemBackground als Hintergrund. Aber immer noch nicht genau das Gleiche wie die Animation der Aktionsleiste.
coolcool1994

1

Wenn Sie einen Welleneffekt wünschen, der die Kreisgrenze nicht überschreitet, können Sie diesen Code überprüfen. Es funktioniert perfekt für mich. Denken Sie daran, Sie müssen id = @ android: id / mask in ripple_blue.xml angeben

<ImageButton
    android:id="@+id/send_password_to_mail_image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/ripple_blue"
    android:src="@drawable/ic_filter" />

ripple_blue.xml

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorRipple">

    <item android:id="@android:id/mask">

        <shape android:shape="oval">
            <solid android:color="@color/colorWindowBackground"/>
        </shape>

    </item>

    <item android:id="@android:id/background">

        <shape android:shape="oval">
            <solid android:color="@color/colorWindowBackground"/>
        </shape>

    </item>

</ripple>

color.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <color name="colorWindowBackground">#F2F5FC</color>
    <color name="colorRipple">#0288d1</color>
</resources>


0

In Kotlin / Java können Sie Folgendes tun

fun View.applyCircularRippleEffect() {
    val backgroundResId = context.getResource(android.R.attr.actionBarItemBackground)

    if (backgroundResId != 0) {
        setBackgroundResource(backgroundResId)
        isClickable = true
        isFocusable = true
    }
}

// getResource extension
fun Context.getResource(resourceId: Int): Int {
    val out = TypedValue()
    theme.resolveAttribute(resourceId, out, true)

    return out.resourceId
}

context.getResource nicht gefunden
Rahul Mandaliya

@ RahulMandaliya danke für den Kommentar. Mein schlechtes, es war meine benutzerdefinierte Erweiterungsmethode.
Fügte
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.