Pracowałem głównie z iOS i przyzwyczaiłem się do bardzo płynnych i płynnych animacji zmian ekranu. Pracuję teraz nad aplikacją na Androida i nie mogę przez całe życie uzyskać transakcji fragmentacji, aby płynnie dodawać/zamieniać fragment.Jak uzyskać płynne animacje transakcji fragmentów na Androidzie
Mój set up przedstawia się następująco: MainActivity
ma FrameLayout
dla swojej xml, który od razu załadować FragmentA
się na MainActivity
„s OnCreate
. Moja aplikacja następnie zastąpi z FragmentB
, , , ect. Moja cała aplikacja ma 1 aktywność.
na kliknięcia przycisku nazywam następujące czynności, aby dodać/wymienić aktualny fragment:
getFragmentManager()
.beginTransaction()
.setCustomAnimations(R.animator.slide_in, android.R.animator.fade_out, android.R.animator.fade_in, R.animator.slide_out)
.addToBackStack(null)
.add(R.id.fragment_1, fragment)
.commit();
slide_in.xml wygląda (slide_out.xml jest oczywiście odwrotnie):
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/linear"
android:propertyName="xFraction"
android:valueType="floatType"
android:valueFrom="1.0"
android:valueTo="0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>
przesuwne w i obecnie jestem animowanie xFraction który mam podklasy LinearLayout
zrobić tak:
public class SlidingLinearLayout extends LinearLayout {
private float yFraction = 0;
private float xFraction = 0;
public SlidingLinearLayout(Context context) {
super(context);
}
public SlidingLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private ViewTreeObserver.OnPreDrawListener preDrawListener = null;
public void setYFraction(float fraction) {
this.yFraction = fraction;
if (getHeight() == 0) {
if (preDrawListener == null) {
preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(preDrawListener);
setYFraction(yFraction);
return true;
}
};
getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
return;
}
float translationY = getHeight() * fraction;
setTranslationY(translationY);
}
public float getYFraction() {
return this.yFraction;
}
public void setXFraction(float fraction) {
this.xFraction = fraction;
if (getWidth() == 0) {
if (preDrawListener == null) {
preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(preDrawListener);
setXFraction(xFraction);
return true;
}
};
getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
return;
}
float translationX = getWidth() * fraction;
setTranslationX(translationX);
}
public float getxFraction() {
return xFraction;
}
}
Więc mój problem jest przez większość czasu, kiedy najpierw kliknąłem przycisk, aby dodać/zastąpić fragment, nie otrzymuję animacji, którą po prostu wyskakuje na miejsce. Jednak więcej razy, gdy naciśniesz przycisk Wstecz, a fragment wyskoczy z backstacku, animacja zostanie wykonana zgodnie z oczekiwaniami. Czuję, że jest to problem z inicjalizacją podczas próby animowania. Kiedy fragment jest w pamięci i animowany poza ekranem, robi to o wiele lepiej, niż gdy tworzony jest nowy fragment, a następnie animowany na ekranie. Ciekaw jestem, czy inni tego doświadczyli, a jeśli tak, to jak to rozwiązali.
To jest irytacja, która nękała moją twórczość na Androida, którą chciałbym odpocząć! Każda pomoc będzie bardzo ceniona. Dzięki!
Ostatnio miałem ten sam problem. Po raz pierwszy przejście przebiega, jest trochę janky. Odkryłem, że wyeliminowanie niepotrzebnych alfów pomaga, ale nie usuwa całkowicie problemu. – Eliezer