android - fragments - overridependingtransition fragment
Fragmento de animación de transición perdida después del cambio de configuración (5)
Estoy insertando Fragmentos en la Actividad usando este código:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fm = getFragmentManager();
String tag = "simple";
Fragment fr = fm.findFragmentByTag(tag);
if (fr == null)
{
SimpleFragment simpleFragment = new SimpleFragment();
FragmentTransaction transaction = fm.beginTransaction();
transaction.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out,
android.R.animator.fade_in, android.R.animator.fade_out);
transaction.add(R.id.main_layout, simpleFragment, tag);
transaction.addToBackStack(tag);
transaction.commit();
}
}
El código de fragmentos es:
public class SimpleFragment extends ListFragment
{
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
getView().setBackgroundColor(Color.YELLOW);
}
}
Cuando saco el fragmento de backstack a través del botón Atrás justo después del lanzamiento, todo está bien y puedo ver la animación de fundido. Pero si giro el dispositivo y presiono el botón Atrás, el fragmento desaparece sin animación.
¿Es este comportamiento de Android o estoy haciendo algo mal?
EDITAR: Parece que después de la rotación, FragmentManager no restauró las animaciones (ingreseAnim, exitAnim, popEnterAnim y popExitAnim) para BackStackEntry.
Volcado FragmentManager (sin rotación):
Active Fragments in 4087d668:
#0: SimpleFragment{408883b0 #0 id=0x7f050000 simple}
mFragmentId=#7f050000 mContainerId#=7f050000 mTag=simple
mState=4 mIndex=0 mWho=android:fragment:0 mBackStackNesting=1
mAdded=true mRemoving=false mResumed=true mFromLayout=false mInLayout=false
mHidden=false mDetached=false mRetainInstance=false mRetaining=false mHasMenu=false
mFragmentManager=FragmentManager{4087d668 in ListViewFragmentsActivity{4087d588}}
mImmediateActivity=my.app.ListViewFragmentsActivity@4087d588
mActivity=my.app.ListViewFragmentsActivity@4087d588
mNextAnim=17498112
mContainer=android.widget.RelativeLayout@408876d8
mView=android.widget.FrameLayout@40888a70
Added Fragments:
#0: SimpleFragment{408883b0 #0 id=0x7f050000 simple}
Back Stack:
#0: android.app.BackStackRecord@408884b8
mName=simple mIndex=0 mCommitted=true
mEnterAnim=#10b0000 mExitAnim=#10b0001
Operations:
Op #0:
cmd=1 fragment=SimpleFragment{408883b0 #0 id=0x7f050000 simple}
enterAnim=17498112 exitAnim=17498113
popEnterAnim=17498112 popExitAnim=17498113
Back Stack Indices:
#0: android.app.BackStackRecord@408884b8
FragmentManager misc state:
mCurState=5 mStateSaved=false mDestroyed=false
Volcado FragmentManager (después de la rotación):
Active Fragments in 40877f38:
#0: SimpleFragment{40878858 #0 id=0x7f050000 simple}
mFragmentId=#7f050000 mContainerId#=7f050000 mTag=simple
mState=4 mIndex=0 mWho=android:fragment:0 mBackStackNesting=1
mAdded=true mRemoving=false mResumed=true mFromLayout=false mInLayout=false
mHidden=false mDetached=false mRetainInstance=false mRetaining=false mHasMenu=false
mFragmentManager=FragmentManager{40877f38 in ListViewFragmentsActivity{40877e58}}
mImmediateActivity=my.app.ListViewFragmentsActivity@40877e58
mActivity=my.app.ListViewFragmentsActivity@40877e58
mContainer=android.widget.RelativeLayout@4087ed50
mView=android.widget.FrameLayout@4087fc00
Added Fragments:
#0: SimpleFragment{40878858 #0 id=0x7f050000 simple}
Back Stack:
#0: android.app.BackStackRecord@40878a78
mName=simple mIndex=0 mCommitted=false
Operations:
Op #0:
cmd=1 fragment=SimpleFragment{40878858 #0 id=0x7f050000 simple}
Back Stack Indices:
#0: android.app.BackStackRecord@40878a78
FragmentManager misc state:
mCurState=5 mStateSaved=false mDestroyed=false
Como solución para esto, puede usar los métodos onCreateAnimator / onCreateAnimation en sus fragmentos.
Por ejemplo, para la implementación de fragmentos nativos:
@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
if (enter) {
return AnimatorInflater.loadAnimator(getActivity(), R.animator.slide_in_top);
} else {
return AnimatorInflater.loadAnimator(getActivity(), R.animator.fade_out);
}
}
La misma técnica para apoyar fragmentos de biblioteca con Animación en su lugar. En este caso, también tiene más control sobre cómo le gustaría reproducir la animación dependiendo del estado del fragmento y / o argumentos.
De acuerdo, este es un error que también es un problema para la biblioteca nativa (no solo para la biblioteca de soporte).
La única solución alternativa que puedo sugerir es crear tu propia pila de respaldo y luego manejarla. Volver con tu propia implementación personalizada configurando la animación correcta a medida que retrocedes en tu propia pila.
Este error se solucionó hace unos días en la nueva biblioteca de soporte 23.3.0
. https://code.google.com/p/android/issues/detail?id=25994#c36
Puede usar onCreateAnimation plus AnimationUtils para cada fragmento en lugar de transaction.setCustomAnimations (..). También para omitir la animación durante la restauración, tenga en cuenta sobre la bandera boleean.
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
mIsRestoring = savedInstanceState != null;
...
}
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
if (mIsRestoring) {
mIsRestoring = false;
return null;
}
if (enter) {
return AnimationUtils.loadAnimation(getContext(), R.anim.enter_from_right);
} else {
return AnimationUtils.loadAnimation(getContext(), R.anim.exit_to_left);
}
}
Una sugerencia alternativa para evitar este problema es descargar la fuente de la biblioteca de soporte y realizar el cambio que sugerí en el defecto ( http://code.google.com/p/android/issues/detail?id=25994 ). , por supuesto, esto significa mantener una copia de la biblioteca de soporte usted mismo y no poder usar el soporte nativo, sin embargo, eso depende de cuán importante es para usted este problema.