Bonjour les bons programmeurs de débordement de pile! J'ai passé une bonne semaine avec ce problème et suis maintenant très désespérée pour une solution.Les fragments imbriqués transition incorrectement
Le scénario
J'utilise android.app.Fragment est à ne pas confondre avec les fragments de soutien.
J'ai 6 fragments d'enfant nommé:
FragmentOne
FragmentTwo
FragmentThree
FragmentA
FragmentB
FragmentC
J'ai deux fragments parents nommé:
FragmentNumeric
FragmentAlpha
J'ai 1 activité nommée:
MainActivity
Ils se comportent dans les domaines suivants:
- fragments d'enfants sont des fragments qui montrent qu'une vue, ils ne montrent pas, ni contiennent des fragments.
- Les fragments parents remplissent toute leur vue avec un seul fragment enfant. Ils sont capables de remplacer le fragment enfant par d'autres fragments enfants.
- L'activité remplit la plus grande partie de sa vue avec un fragment parent. Il peut le remplacer par d'autres fragments parents. Ainsi, à tout moment, l'écran ne montre qu'un seul fragment enfant.
Comme vous l'avez sans doute deviné,
FragmentNumeric
montre des fragments d'enfant FragmentOne
, FragmentTwo
et FragmentThree
.
FragmentAlpha
montre des fragments d'enfant FragmentA
, FragmentB
et FragmentC
.
Le problème
Je suis en train de transition/animer des fragments parents et enfants. L'enfant fragmente la transition en douceur et comme prévu. Cependant, lorsque je passe à un nouveau fragment de parent, il semble terrible. Le fragment enfant ressemble à une transition indépendante de son fragment parent.Et le fragment enfant semble également être supprimé du fragment parent. Un gif de celui-ci peut être consulté ici https://imgur.com/kOAotvk. Notez ce qui se passe lorsque je clique sur Afficher l'Alpha.
La question la plus proche & les réponses que j'ai pu trouver sont ici: Nested fragments disappear during transition animation cependant toutes les réponses sont des hacks insatisfaisants.
XML Animator fichiers
je les effets suivants (animateur durée est longue à des fins de test):
fragment_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="xFraction"
android:valueFrom="1.0"
android:valueTo="0" />
</set>
fragment_exit.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="xFraction"
android:valueFrom="0"
android:valueTo="-1.0" />
</set>
fragment_pop.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="xFraction"
android:valueFrom="0"
android:valueTo="1.0" />
</set>
fragment_push.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="xFraction"
android:valueFrom="-1.0"
android:valueTo="0" />
</set>
fragment_nothing.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000" />
</set>
MainActivity.kt
choses à considérer: Le premier fragment de parent, FragmentNumeric, ne pas entrer dans des effets de sorte que son toujours prêt à l'activité et n'a pas d'effets de sortie parce que rien est sortie. J'utilise aussi FragmentTransaction#add
avec elle alors que FragmentAlpha utilise FragmentTransaction#replace
class MainActivity : AppCompatActivity {
fun showFragmentNumeric(){
this.fragmentManager.beginTransaction()
.setCustomAnimations(R.animator.fragment_nothing,
R.animator.fragment_nothing,
R.animator.fragment_push,
R.animator.fragment_pop)
.add(this.contentId, FragmentNumeric(), "FragmentNumeric")
.addToBackStack("FragmentNumeric")
.commit()
}
fun showFragmentAlpha(){
this.fragmentManager.beginTransaction()
.setCustomAnimations(R.animator.fragment_enter,
R.animator.fragment_exit,
R.animator.fragment_push,
R.animator.fragment_pop)
.replace(this.contentId, FragmentAlpha(), "FragmentAlpha")
.addToBackStack("FragmentAlpha")
.commit()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
showFragmentNumeric()
}
}
}
FragmentNumeric
Est-ce la même chose que l'activité en termes de montrer rapidement son premier fragment d'enfant.
class FragmentNumeric : Fragment {
fun showFragmentOne(){
this.childFragmentManager.beginTransaction()
.setCustomAnimations(R.animator.fragment_nothing,
R.animator.fragment_nothing,
R.animator.fragment_push,
R.animator.fragment_pop)
.add(this.contentId, FragmentOne(), "FragmentOne")
.addToBackStack("FragmentOne")
.commit()
}
fun showFragmentTwo(){
this.childFragmentManager.beginTransaction()
.setCustomAnimations(R.animator.fragment_enter,
R.animator.fragment_exit,
R.animator.fragment_push,
R.animator.fragment_pop)
.replace(this.contentId, FragmentTwo(), "FragmentTwo")
.addToBackStack("FragmentTwo")
.commit()
}
fun showFragmentThree(){
this.childFragmentManager.beginTransaction()
.setCustomAnimations(R.animator.fragment_enter,
R.animator.fragment_exit,
R.animator.fragment_push,
R.animator.fragment_pop)
.replace(this.contentId, FragmentThree(), "FragmentThree")
.addToBackStack("FragmentThree")
.commit()
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (savedInstanceState == null) {
if (this.childFragmentManager.backStackEntryCount <= 1) {
showFragmentOne()
}
}
}
}
autres fragments
FragmentAlpha suit le même schéma que FragmentNumeric, en remplaçant Fragments un, deux et trois avec des fragments A, B et C respectivement. Les fragments enfants affichent simplement la vue XML suivante et définissent son écouteur de texte et de bouton de manière dynamique pour appeler une fonction du fragment parent ou de l'activité.
view_child_example.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/view_child_example_header"
style="@style/Header"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/view_child_example_button"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
En utilisant dague et quelques contrats que j'ai les fragments enfants rappel à leurs fragments parents et des activités d'hébergement en faisant quelque chose comme ci-dessous:
FragmentOne définit le bouton clic auditeur à faire:
(parentFragment as FragmentNumeric).showFragmentTwo()
FragmentTwo définit le bouton clic auditeur à faire:
(parentFragment as FragmentNumeric).showFragmentThree()
FragmentThree est différent, il sera mis à l'auditeur de clic à faire:
(activity as MainActivity).showFragmentAlpha()
Quelqu'un at-il une solution à ce problème?
Update 1
J'ai ajouté un exemple de projet tel que demandé: https://github.com/zafrani/NestedFragmentTransitions
Une différence et que de celui de ma vidéo d'origine est le fragment parent n'utilise une vue avec la propriété xFraction. Il semble donc que l'animation d'entrée n'a plus cet effet de chevauchement. Cependant, il supprime toujours le fragment enfant du parent et les anime côte à côte. Une fois l'animation terminée, le fragment 3 est remplacé par le fragment A instantanément.
Update 2
Les deux vues fragment d'enfant et le parent utilisent la propriété xFraction. La clé consiste à supprimer l'animation childs lorsque le parent est en train d'animer.
La question est déjà super claire, mais puisque vous semblez avoir un projet propre montrant le problème, il serait cool si vous pouviez le télécharger quelque part. – natario
S'il vous plaît mettre à jour Gifs, semble qu'il manque. UPD. Désolé, mon mal, a trouvé l'image. – GensaGames
@natario J'ai ajouté un lien github. – zafrani