Angenommen, ich habe ein vertikales lineares Layout mit:
[v1]
[v2]
Standardmäßig hat v1 sichtbar = GONE. Ich möchte v1 mit einer erweiterten Animation zeigen und gleichzeitig v2 nach unten drücken.
Ich habe so etwas versucht:
Animation a = new Animation()
{
int initialHeight;
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final int newHeight = (int)(initialHeight * interpolatedTime);
v.getLayoutParams().height = newHeight;
v.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
initialHeight = height;
}
@Override
public boolean willChangeBounds() {
return true;
}
};
Aber mit dieser Lösung habe ich ein Blinken, wenn die Animation beginnt. Ich denke, es liegt daran, dass v1 in voller Größe angezeigt wird, bevor die Animation angewendet wird.
Mit Javascript ist dies eine Zeile von jQuery! Gibt es eine einfache Möglichkeit, dies mit Android zu tun?
a.setDuration(((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density)) * 4)
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
undv.getLayoutParams().height = interpolatedTime == 1 ? targetHeight : (int)(targetHeight * interpolatedTime);
das hat bei mir funktioniert!Ich habe versucht, eine meiner Meinung nach sehr ähnliche Animation zu erstellen, und eine elegante Lösung gefunden. Dieser Code setzt voraus, dass Sie immer von 0-> h oder h-> 0 gehen (h ist die maximale Höhe). Die drei Konstruktorparameter sind view = die zu animierende Ansicht (in meinem Fall eine Webansicht), targetHeight = die maximale Höhe der Ansicht und down = ein Boolescher Wert, der die Richtung angibt (true = erweitern, false = reduzieren).
quelle
Ich bin heute über das gleiche Problem gestolpert und ich denke, die wirkliche Lösung für diese Frage ist diese
Sie müssen diese Eigenschaft für alle obersten Layouts festlegen, die an der Verschiebung beteiligt sind. Wenn Sie jetzt die Sichtbarkeit eines Layouts auf GONE setzen, nimmt das andere den Platz ein, während das verschwindende ihn freigibt. Es wird eine Standardanimation geben, die eine Art "Ausblenden" darstellt, aber ich denke, Sie können dies ändern - aber die letzte, die ich noch nicht getestet habe.
quelle
Ich habe die Lösung von @LenaYan genommen, die für mich nicht richtig funktioniert hat ( weil die Ansicht vor dem Reduzieren und / oder Erweitern in eine Ansicht mit einer Höhe von 0 umgewandelt wurde ) und einige Änderungen vorgenommen.
Jetzt funktioniert es hervorragend , indem Sie die vorherige Höhe der Ansicht übernehmen und mit dieser Größe erweitern. Das Zusammenfallen ist dasselbe.
Sie können den folgenden Code einfach kopieren und einfügen:
Verwendungszweck:
Leicht genug!
Danke LenaYan für den ersten Code!
quelle
Eine Alternative besteht darin, eine Skalierungsanimation mit den folgenden Skalierungsfaktoren zum Erweitern zu verwenden:
und zum Zusammenbruch:
quelle
@ Tom Esterez ' Antwort , aber aktualisiert, um view.measure () ordnungsgemäß für Android zu verwenden. GetMeasuredHeight gibt falsche Werte zurück!
quelle
Ok, ich habe gerade eine SEHR hässliche Lösung gefunden:
Fühlen Sie sich frei, eine bessere Lösung vorzuschlagen!
quelle
View.onMeause(widthMeasureSpec, heightMeasureSpec)
ob der Aufruf einen kleinen Fehler enthält, daher sollten die Angaben zu Breite und Höhe ausgetauscht werden.quelle
Wenn Sie nicht vollständig expandieren oder kollabieren möchten, finden Sie hier eine einfache HeightAnimation.
Verwendungszweck:
quelle
Ich habe die aktuell akzeptierte Antwort von Tom Esterez angepasst , die funktionierte, aber eine abgehackte und nicht sehr flüssige Animation hatte. Meine Lösung ersetzt im Grunde die
Animation
durch eineValueAnimator
, die mit einerInterpolator
Ihrer Wahl ausgestattet werden kann, um verschiedene Effekte wie Überschwingen, Abprallen, Beschleunigen usw. zu erzielen.Diese Lösung eignet sich hervorragend für Ansichten mit einer dynamischen Höhe (z. B. mithilfe von
WRAP_CONTENT
), da zuerst die tatsächlich erforderliche Höhe gemessen und dann auf diese Höhe animiert wird.Sie rufen dann einfach an
expand( myView );
odercollapse( myView );
.quelle
v.measure()
und jetzt funktioniert es perfekt. Vielen Dank!Unter Verwendung der Kotlin-Erweiterungsfunktionen ist dies eine getestete und kürzeste Antwort
Rufen Sie einfach animateVisibility (Erweitern / Reduzieren) in einer beliebigen Ansicht auf.
quelle
Neben der hervorragenden Antwort von Tom Esterez und dem hervorragenden Update von Erik B dachte ich, ich würde meine eigene Einstellung veröffentlichen und die Expansions- und Kontraktionsmethoden zu einer einzigen komprimieren . Auf diese Weise könnten Sie beispielsweise eine Aktion wie diese ausführen ...
... die die folgende Methode aufruft und sie herausfinden lässt, was nach jedem onClick () zu tun ist ...
quelle
Ich möchte der sehr hilfreichen Antwort oben etwas hinzufügen . Wenn Sie die Höhe nicht kennen, mit der Sie enden werden, da Ihre Ansichten .getHeight () 0 zurückgeben, können Sie Folgendes tun, um die Höhe zu ermitteln:
Wobei DUMMY_HIGH_DIMENSIONS die Breite / Höhe (in Pixel) ist, auf die Ihre Ansicht beschränkt ist ... eine große Anzahl ist sinnvoll, wenn die Ansicht mit einer ScrollView gekapselt ist.
quelle
Dies ist ein Ausschnitt, mit dem ich die Breite einer Ansicht (LinearLayout) mit Animation geändert habe.
Der Code soll entsprechend der Zielgröße erweitert oder verkleinert werden. Wenn Sie eine fill_parent-Breite wünschen, müssen Sie die übergeordnete .getMeasuredWidth als Zielbreite übergeben, während Sie das Flag auf true setzen.
Hoffe es hilft einigen von euch.
}}
quelle
resizeAnim.start()
. Habe es auch mit und ohne versuchtsetFillAfter(true)
.startAnimation(resizeAnim)
auf die Aussicht anrufen .Verwenden Sie für eine reibungslose Animation den Handler mit der Ausführungsmethode ..... und genießen Sie die Animation zum Erweitern / Reduzieren
Und rufen Sie mit diesem Code an:
Andere Lösung ist:
quelle
kombinierte Lösungen von @Tom Esterez und @Geraldo Neto
quelle
Ja, ich habe den obigen Kommentaren zugestimmt. In der Tat scheint es das Richtige (oder zumindest das Einfachste?) Zu sein, eine anfängliche Layouthöhe von "0px" (in XML) anzugeben - und dann können Sie ein anderes Argument für "toHeight" ( dh die "endgültige Höhe") zum Konstruktor Ihrer benutzerdefinierten Animationsunterklasse, z. B. im obigen Beispiel, würde es ungefähr so aussehen:
Wie auch immer, hoffe das hilft! :) :)
quelle
Hier ist meine Lösung. Ich denke es ist einfacher. Es erweitert nur die Ansicht, kann aber einfach erweitert werden.
quelle
Ich denke, die einfachste Lösung besteht darin
android:animateLayoutChanges="true"
, IhreLinearLayout
Ansicht festzulegen und dann einfach anzuzeigen / auszublenden, indem Sie die Sichtbarkeit festlegen. Funktioniert wie ein Zauber, aber Sie haben keine Kontrolle über die Animationsdauerquelle
Du bist auf dem richtigen Weg. Stellen Sie sicher, dass v1 unmittelbar vor Beginn der Animation eine Layouthöhe von Null hat. Sie möchten Ihr Setup so initialisieren, dass es wie das erste Bild der Animation aussieht, bevor Sie die Animation starten.
quelle
Dies war meine Lösung, ich
ImageView
wächst von100%
zu200%
und kehre zu seiner ursprünglichen Größe zurück, indem ich zwei Animationsdateien imres/anim/
Ordner verwendeanim_grow.xml
anim_shrink.xml
Senden Sie eine
ImageView
an meine MethodesetAnimationGrowShrink()
setAnimationGrowShrink()
Methode:quelle
Dies ist eine ordnungsgemäß funktionierende Lösung, ich habe sie getestet:
Exapnd:
Zusammenbruch:
Wertanimator:
Ansicht v ist die zu animierende Ansicht, PARENT_VIEW ist die Containeransicht, die die Ansicht enthält.
quelle
Mit droidQuery ist das ganz einfach . Betrachten Sie für den Start dieses Layout:
Wir können die Höhe
100dp
mit dem folgenden Code auf den gewünschten Wert animieren - sagen wir :Dann
droidQuery
zum Animieren verwenden. Der einfachste Weg ist damit:Um die Animation ansprechender zu gestalten, sollten Sie eine Lockerung hinzufügen:
Sie können die Dauer auch
AnimationOptions
mithilfe derduration()
Methode ändern oder festlegen, was passiert, wenn die Animation endet. Versuchen Sie für ein komplexes Beispiel:quelle
Beste Lösung für Ansichten zum Erweitern / Reduzieren:
quelle
onCheckedChanged
.Sie können einen ViewPropertyAnimator mit einer leichten Drehung verwenden. Skalieren Sie die Ansicht zum Reduzieren auf eine Höhe von 1 Pixel und blenden Sie sie dann aus. Zeigen Sie es zum Erweitern an und erweitern Sie es dann auf seine Höhe.
Der Pivot teilt der Ansicht mit, von wo aus skaliert werden soll. Die Standardeinstellung befindet sich in der Mitte. Die Dauer ist optional (Standard = 1000). Sie können auch den zu verwendenden Interpolator wie einstellen
.setInterpolator(new AccelerateDecelerateInterpolator())
quelle
Ich habe eine Version erstellt, in der Sie keine Layouthöhe angeben müssen, daher ist die Verwendung viel einfacher und sauberer. Die Lösung besteht darin, die Höhe im ersten Frame der Animation zu ermitteln (sie ist zu diesem Zeitpunkt verfügbar, zumindest während meiner Tests). Auf diese Weise können Sie eine Ansicht mit einer beliebigen Höhe und einem beliebigen unteren Rand bereitstellen.
Es gibt auch einen kleinen Hack im Konstruktor - der untere Rand ist auf -10000 eingestellt, damit die Ansicht vor der Transformation ausgeblendet bleibt (verhindert Flimmern).
quelle
Verwenden Sie ValueAnimator:
quelle
mainView.getLayoutParams().height = height
.quelle
Die Klasse kann folgendermaßen aufgerufen werden
quelle
Basierend auf Lösungen von @Tom Esterez und @Seth Nelson (Top 2) habe ich sie vereinfacht. Neben den ursprünglichen Lösungen hängt es nicht von den Entwickleroptionen (Animationseinstellungen) ab.
quelle