Der Ripple-Effekt auf der Oberseite des Bild - Android
Ich habe experimentiert mit der ripple animation in meinem aktuellen Nebenprojekt. Ich habe einige Probleme bei der Suche eine "elegante" Lösung zu benutzen, in bestimmten Situationen für touch-Ereignisse. Nämlich mit Bildern, vor allem in der Listen -, raster-und Recycling-Ansichten. Die animation fast immer scheint zu animieren, hinter die Ansicht, nicht die oben drauf. Dies ist ein keines Problem in Buttons und TextViews aber wenn Sie ein GridView-Bilder, die ripple wird hinter oder unter dem eigentlichen Bild. Offensichtlich ist dies nicht das, was ich will, und zwar gibt es Lösungen, die halte ich für ein work-around, ich hoffe es ist etwas einfacher, ich bin nur nicht bewusst.
Ich den folgenden code verwenden, erreichen Sie eine benutzerdefinierte raster-Ansicht mit Bild. Ich gebe volle code KLICKEN SIE HIER so können Sie entlang Folgen, wenn Sie wählen.
Nun nur die wichtigen Sachen. Um mein Bild zu animieren, auf berühren ich brauche diese
button_ripple.xml
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/cream_background">
<item>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed -->
<item
android:drawable="@color/button_selected"
android:state_pressed="true"/>
<!-- Selected -->
<item
android:drawable="@color/button_selected"
android:state_selected="true"/>
<!-- Focus -->
<item
android:drawable="@color/button_selected"
android:state_focused="true"/>
<!-- Default -->
<item android:drawable="@color/transparent"/>
</selector>
</item>
</ripple>
custom_grid.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<ImageView
android:id="@+id/sceneGridItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_ripple"
android:gravity="center_horizontal"/>
</LinearLayout>
activity_main.xml
<GridView
android:id="@+id/sceneGrid"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:verticalSpacing="15dp"
android:numColumns="5" />
Die Zeile, in der alle Magie und Probleme auftreten, ist, wenn ich den hintergrund. Dies hat zwar in der Tat, geben Sie mir einen ripple animation auf meinem Bildansicht, es animiert hinter Bildansicht. Ich möchte die animation erscheinen oben des Bildes. Also ich habe versucht ein paar verschiedene Dinge wie
Einstellung das gesamte raster hintergrund button_ripple.
<GridView
android:id="@+id/sceneGrid"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:verticalSpacing="15dp"
android:background="@drawable/button_ripple"
android:numColumns="5" />
Es tut genau das, was man denkt, jetzt ist das gesamte Netz hat einen semi-transparenten hintergrund und egal was ich drücke das gesamte grid animiert von der Mitte des Rasters. Das ist zwar irgendwie cool, es ist nicht, was ich will.
Einstellung root/parent hintergrund button_ripple.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="@drawable/button_ripple"
android:orientation="horizontal">
Bereich ist jetzt größer und füllt die ganze Zelle des Rasters (nicht nur die Bild), aber nicht bringen es auf der Vorderseite.
Ändern custom_grid.xml zu einem RelativeLayout und das setzen von zwei ImageViews übereinander
custom_grid.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/gridItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
<ImageView
android:id="@+id/gridItemOverlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:background="@drawable/button_ripple" />
</RelativeLayout>
CustomGridAdapter.java
....
gridItemOverLay = (ImageView) findViewById(R.id.gridItemOverlay);
gridItemOverlay.bringToFront();
Dieser funktioniert. Jetzt ist der Boden Bildansicht enthält mein Bild, und die top-animiert, was die illusion einer ripple animation oben mein Bild. Aber ganz ehrlich das ist eine Arbeit um. Ich glaube, das ist nicht wie es gedacht war. So bitte ich Sie feinen Leute, gibt es eine bessere Möglichkeit oder sogar einen anderen Weg?
- Bitte zählen XML für die button_ripple drawable.
- Hinzugefügt wie gewünscht
- Die <ripple> - element ist nicht ein Selektor, es ist ein layer-Liste. Werfen Sie einen Blick auf die Dokumentation für RippleDrawable.
- Ich habe die Dokumentation gelesen und ich bin immer noch ein bisschen verwirrt. Es war nie klar, was zu tun ist in der Instanz von benutzerdefinierten Adaptern oder mehrere Ressourcen. In diesem Beispiel bin ich füllen mein raster mit bitmaps aus meiner expansion-Ordner in Android/obb. Meine beste Vermutung ist, dass ich die RippleDrawable Konstruktor und wenden Sie Sie jeder Zeit manuell/Programm, ist das richtig?
- Ich benutzte gleicher Weise für die Galerie. Es funktioniert, aber der ripple beginnt immer von der Mitte des Elements. Hast du dasselbe problem oder irgendeine Lösung?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mochte ich android-Entwickler für die Antwort, so beschloss ich zu untersuchen, wie es zu tun Schritt 2 seiner Lösung im code.
Müssen Sie Holen Sie sich dieses Stück code von Jake Wharton hier : https://gist.github.com/JakeWharton/0a251d67649305d84e8a
Dies ist die attrs.xml:
Erstellen Sie jetzt Ihren ForegroundImageView wie so in Ihre layout.xml:
Wird das Bild jetzt ripple.
Anstatt zu versuchen, fügen Sie die welligkeit auf jeden einzelnen Blick in den adapter können Sie einfach fügen Sie es an das GridView-Ebene wie diese:
Vielleicht versuchen Sie eine dieser Lösungen (bekam den Tipp von hier) :
Wickeln Sie das drawable in ein
RippleDrawable
2, bevor Sie es auf dieImageView
:Erweitern
ImageView
und fügen Sie ein Vordergrund-Attribut (wie z.B.FrameLayout
has3). Sehen Sie diese example⁴ von +Chris Dämonen von hinzufügen, um einenLinearLayout
. Wenn Sie dies tun, dann stellen Sie sicher, Sie gehen durch die touch-Koordinaten, so dass die Kräuselung beginnt ab dem richtigen Zeitpunkt:Ich habe eine Bildergalerie (erstellt mit einem
RecyclerView
und einGridLayoutManager
). Das Bild wird mit Picasso. Hinzufügen eines ripple auf das Bild ich umwickelt habe dieImageView
mit einemFrameLayout
. Das Element layout:Hinweis: die
android:foreground
. Es ist nicht das gleiche wieandroid:background
. Ich habe versucht ohneandroid:clickable="true"
undandroid:focusable="true"
und es auch funktioniert, aber es tut nicht weh.Dann fügen Sie eine
ripple.xml
drawable inres/drawable
:Beachten Sie, dass dies zeigt eine semi-transparente Farbe auf der Oberseite des Bildes, wenn das Element ausgewählt ist (für Geräte < 5.0). Sie können es entfernen, wenn Sie es nicht möchten.
Dann fügen Sie die
ripple.xml
drawable mit ripple inres/drawable-v21
:Verwenden Sie die Standard-Kräuselung-Effekt-anstelle des benutzerdefinierten
ripple.xml
, aber es ist wirklich schwer zu sehen auf einem Bild, weil es Grau: