Xin chào các lập trình viên tốt về tràn ngăn xếp! Tôi đã dành một tuần tốt với vấn đề này và bây giờ rất tuyệt vọng cho một giải pháp.Các đoạn lồng nhau được chuyển đổi không chính xác
Kịch bản
Tôi đang sử dụng android.app.Fragment không nên nhầm lẫn với các mảnh vỡ hỗ trợ.
Tôi đã mảnh 6 đứa trẻ có tên:
FragmentOne
FragmentTwo
FragmentThree
FragmentA
FragmentB
FragmentC
Tôi đã fragments 2 mẹ tên là:
FragmentNumeric
FragmentAlpha
Tôi đã 1 hoạt động mang tên:
MainActivity
Họ cư xử theo những điều sau đây:
- mảnh trẻ em là những mảnh vỡ mà chỉ hiển thị một cái nhìn, họ không hiển thị cũng không được chứa các mảnh vỡ.
- Các đoạn gốc điền vào toàn bộ khung nhìn của chúng với một đoạn con duy nhất. Họ có thể thay thế đoạn con với các mảnh con khác.
- Hoạt động này sẽ chiếm hầu hết chế độ xem của nó với một đoạn gốc. Nó có thể thay thế nó bằng các đoạn cha khác. Vì vậy, tại bất kỳ thời điểm nào, màn hình chỉ hiển thị một đoạn con.
Như bạn đã có thể đoán,
FragmentNumeric
thấy mảnh vỡ con FragmentOne
, FragmentTwo
, và FragmentThree
.
FragmentAlpha
hiển thị các đoạn con FragmentA
, FragmentB
và FragmentC
.
Vấn đề
Tôi đang cố gắng để chuyển/động mảnh phụ huynh và trẻ em. Các mảnh vỡ trẻ chuyển tiếp suôn sẻ và như mong đợi. Tuy nhiên khi tôi chuyển sang một đoạn phụ huynh mới, nó trông khủng khiếp. Đoạn con trông giống như nó chạy một quá trình chuyển đổi độc lập từ đoạn cha của nó.Và mảnh con trông giống như nó được loại bỏ khỏi đoạn cha mẹ. Một gif của nó có thể được xem ở đây https://imgur.com/kOAotvk. Lưu ý điều gì sẽ xảy ra khi tôi nhấp vào Hiển thị Alpha.
Câu hỏi gần nhất & câu trả lời Tôi có thể tìm thấy ở đây: Nested fragments disappear during transition animation tuy nhiên tất cả các câu trả lời đều là các lỗi không thỏa mãn.
Animator XML file
Tôi có những tác động làm phim hoạt hình sau (thời gian dài cho mục đích thử nghiệm):
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
Những điều cần xem xét: Đoạn cha mẹ đầu tiên, FragmentNumeric, không có nhập các hiệu ứng để nó luôn sẵn sàng với các hoạt động và không có tác dụng thoát vì không có gì là thoát. Tôi cũng đang sử dụng FragmentTransaction#add
với nó nơi như FragmentAlpha đang sử dụng 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
Liệu điều tương tự như hoạt động về một cách nhanh chóng cho thấy đoạn đứa con đầu lòng của mình.
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()
}
}
}
}
Những mảnh vỡ khác
FragmentAlpha đang theo cùng một khuôn mẫu như FragmentNumeric, thay thế Những mảnh vỡ Một, Hai và Ba với mảnh vỡ A, B và C tương ứng.
Đoạn con chỉ hiển thị chế độ xem XML sau và đặt trình nghe nhấp vào nút văn bản và nút động để gọi hàm từ đoạn hoặc hoạt động gốc.
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>
Sử dụng dao găm và một số hợp đồng tôi có các mảnh vỡ con gọi lại để mảnh cha mẹ của họ và các hoạt động lưu trữ bằng cách làm một cái gì đó giống như dưới đây:
FragmentOne đặt người nghe vào nút nhấp chuột để làm:
(parentFragment as FragmentNumeric).showFragmentTwo()
FragmentTwo đặt người nghe vào nút nhấp chuột để làm:
(parentFragment as FragmentNumeric).showFragmentThree()
FragmentThree là khác nhau, nó sẽ thiết lập các listener nhấp chuột để làm:
(activity as MainActivity).showFragmentAlpha()
Có ai có một giải pháp cho vấn đề này?
Cập nhật 1
Tôi đã thêm một dự án ví dụ như yêu cầu: https://github.com/zafrani/NestedFragmentTransitions
Một sự khác biệt trong đó và rằng từ một trong đoạn video ban đầu của tôi là mảnh mẹ không còn sử dụng một cái nhìn với thuộc tính xFraction. Vì vậy, có vẻ như hoạt ảnh nhập không có hiệu ứng chồng chéo đó nữa. Tuy nhiên nó vẫn loại bỏ các mảnh con từ cha mẹ và animate chúng cạnh nhau. Sau khi hoàn thành hoạt ảnh, Fragment Three sẽ thay thế bằng Fragment A ngay lập tức.
Cập nhật 2
Cả chế độ xem đoạn cha và con đều sử dụng thuộc tính xFraction. Điều quan trọng là để ngăn chặn các hình ảnh động của trẻ khi cha mẹ là hoạt hình.
Câu hỏi đã được siêu rõ ràng, nhưng vì bạn dường như có một dự án sạch sẽ hiển thị vấn đề, nó sẽ được mát mẻ nếu bạn có thể tải nó ở đâu đó. – natario
Vui lòng cập nhật Gifs, có vẻ như nó bị thiếu. UPD. Xin lỗi, xấu của tôi, tìm thấy hình ảnh. – GensaGames
@natario Tôi đã thêm liên kết github. – zafrani