你好程序員的堆棧溢出!我已經花了一週的時間解決了這個問題,現在我非常想要絕望。嵌套片段轉換不正確
場景
我使用android.app.Fragment不與載體片段相混淆。
我有6個孩子命名片段:
FragmentOne
FragmentTwo
FragmentThree
FragmentA
FragmentB
FragmentC
我已2母體片段命名爲:
FragmentNumeric
FragmentAlpha
我已經1個活性命名爲:
MainActivity
他們的表現在以下幾點:
- 兒童片段片段只顯示一個視圖,他們不顯示,也不包含片段。
- 父級片段使用單個子片段填充其整個視圖。他們能夠將子片段替換爲其他子片段。
- 該活動使用父級片段填充其大部分視圖。它可以將其替換爲其他父代片段。 因此,在任何時候屏幕只顯示一個孩子片段。
正如你可能已經猜到,
FragmentNumeric
顯示子片段FragmentOne
,FragmentTwo
和FragmentThree
。
FragmentAlpha
顯示子片段FragmentA
,FragmentB
和FragmentC
。
我試圖轉型/動畫家長和孩子碎片問題。如預期的那樣,孩子的片段順利過渡。但是當我轉換到一個新的父代片段時,它看起來很糟糕。子片段看起來像從其父片段運行獨立轉換。子片段看起來也是從父片段中移除的。它的一個GIF可以在這裏查看https://imgur.com/kOAotvk。注意當我點擊Show Alpha時會發生什麼。
最接近的問題&答案我可以在這裏找到:Nested fragments disappear during transition animation但是,所有的答案都令人不滿。
動畫XML文件
我有以下的動畫效果(持續時間長用於測試目的):
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
需要考慮的事情:第一父片段,FragmentNumeric,沒有進入影響所以它總是準備好與活動,並沒有退出的影響,因爲沒有什麼是退出。其中,作爲FragmentAlpha在迅速顯示出它的第一個孩子片段條款使用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
做同樣的事情作爲活動我還使用FragmentTransaction#add
它。
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()
}
}
}
}
其它片段
FragmentAlpha跟隨相同的圖案FragmentNumeric,用片段A,B和C.替換片段一,二及三。
兒童片段只是顯示以下XML視圖並動態設置其文本和按鈕單擊偵聽器,以從父片段或活動調用函數。
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>
使用匕首和一些合同我有孩子片段回調到它們的父片段,並舉辦活動,通過執行類似下面:
FragmentOne設置按鈕,點擊監聽,這樣做:
(parentFragment as FragmentNumeric).showFragmentTwo()
FragmentTwo設置按鈕,點擊監聽,這樣做:
(parentFragment as FragmentNumeric).showFragmentThree()
FragmentThree不同的是,它會設置的點擊收聽做:
(activity as MainActivity).showFragmentAlpha()
有沒有人有這個問題的解決方案?
更新1
我添加了一個例子項目的要求:https://github.com/zafrani/NestedFragmentTransitions
從一個在我的原始視頻在它和差變成父片段不再使用視圖與xFraction屬性。所以看起來輸入動畫不再有重疊效果。但它仍然會從父級刪除子級片段並將它們並排設置。動畫完成後,Fragment Three即刻替換爲Fragment A。
更新2
父級和子級片段視圖都使用xFraction屬性。關鍵是在父母動畫時抑制孩子動畫。
這個問題已經非常明確,但由於您似乎有一個乾淨的項目來顯示問題,如果您可以將它上載到某個位置,它將會很酷。 – natario
請更新GIF,看起來不見了。 UPD。對不起,我的壞,找到了圖像。 – GensaGames
@natario我已經添加了一個github鏈接。 – zafrani