$30 off During Our Annual Pro Sale. View details »

Что нового в Fragment 1.4

Что нового в Fragment 1.4

Видео версия https://youtu.be/UWuuqbNIWpE

Крайний релиз Jetpack Fragment вышел очень интересным на фичи, что заслужил озвучить изменения в отдельном видео, а именно:
🔥 Новый менеджер состояний
🔥 Несколько back stack
🔥 FragmentStrictMode
💪 Новые проверки кода в Android Lint
🚀 Улучшение работы анимаций
🔨 Исправление багов в работе ЖЦ Fragment

Kirill Rozov

December 12, 2021
Tweet

More Decks by Kirill Rozov

Other Decks in Programming

Transcript

  1. Fragment 1.4 Кирилл Розов, Android Broadcast, декабрь 2021 Как похорошели

    Fragment
  2. FragmentContainer.getFragment

  3. <fragment android:layout_width="match_parent" android:layout_height="match_parent" android:name="dev.androidbroadcast.fragmentdemo.FirstFragment" android:tag="first" !"

  4. <androidx.fragment.app.FragmentContainerView android:layout_width="match_parent" android:layout_height="match_parent" android:name="dev.androidbroadcast.fragmentdemo.FirstFragment" android:tag="first" !"

  5. val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container) val homeFragment: HomeFragment = fragment as

    HomeFragment
  6. val fragmentContainer: FragmentContainerView = … val homeFragment: HomeFragment = fragmentContainer.getFragment()

  7. Новый менеджер состояний теперь единственный

  8. Что изменили ! Исправили множество багов с навигацией ! Управление

    состоянием Fragment ! Заложена поддержка для множественного back stack ! Упрощение жизненного цикла Fragment [результатов пока не видно]
  9. None
  10. None
  11. FragmentStrictMode

  12. supportFragmentManager.strictModePolicy = FragmentStrictMode.Policy.Builder() .penaltyDeath() .penaltyListener(…) .penaltyLog() .detectFragmentReuse() .detectFragmentTagUsage() .detectRetainInstanceUsage() .detectTargetFragmentUsage()

    .detectWrongFragmentContainer() .detectSetUserVisibleHint() .build()
  13. supportFragmentManager.strictModePolicy = FragmentStrictMode.Policy.Builder() .penaltyDeath() .penaltyListener(…) .penaltyLog() .detectFragmentReuse() .detectFragmentTagUsage() .detectRetainInstanceUsage() .detectTargetFragmentUsage()

    .detectWrongFragmentContainer() .detectSetUserVisibleHint() .build()
  14. penaltyDeath 2021-12-11 17:08:56.170 12010-12010/dev.androidbroadcast.fragmentdemo E/FragmentStrictMode: Policy violation with PENALTY_DEATH in

    dev.androidbroadcast.fragmentdemo.FirstFragment androidx.fragment.app.strictmode.SetUserVisibleHintViolation: Attempting to set user visible hint to true for fragment FirstFragment{300fd8d} (9fbf6047-2ed5-4952-b7bd-4d513035c141 id=0x7f0800c5) at androidx.fragment.app.strictmode.FragmentStrictMode.onSetUserVisibleHint(FragmentStrictMode.kt:131) at androidx.fragment.app.Fragment.setUserVisibleHint(Fragment.java:1335) at dev.androidbroadcast.fragmentdemo.FirstFragment.onViewCreated(FirstFragment.kt:26) at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3019) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841) at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777) at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841) at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784) at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262) at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478) at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
  15. penaltyLog 2021-12-11 17:10:19.516 12163-12163/dev.androidbroadcast.fragmentdemo D/FragmentStrictMode: Policy violation in dev.androidbroadcast.fragmentdemo.FirstFragment androidx.fragment.app.strictmode.SetUserVisibleHintViolation:

    Attempting to set user visible hint to true for fragment FirstFragment{300fd8d} (e2010f02-eb83-416b-a7ac-05aaa3befd12 id=0x7f0800c5) at androidx.fragment.app.strictmode.FragmentStrictMode.onSetUserVisibleHint(FragmentStrictMode.kt:131) at androidx.fragment.app.Fragment.setUserVisibleHint(Fragment.java:1335) at dev.androidbroadcast.fragmentdemo.FirstFragment.onViewCreated(FirstFragment.kt:26) at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3019) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841) at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777) at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841) at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784) at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262) at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478) at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
  16. penaltyListener FragmentStrictMode.Policy.Builder() .penaltyListener() { vialotation: Violation !" }

  17. penaltyListener FragmentStrictMode.Policy.Builder() .penaltyListener() { vialotation: Violation !" } Firebase.crashlytics.recordException(vialotation)

  18. supportFragmentManager.strictModePolicy = FragmentStrictMode.Policy.Builder() .penaltyDeath() .penaltyListener(…) .penaltyLog() .detectFragmentReuse() .detectFragmentTagUsage() .detectRetainInstanceUsage() .detectTargetFragmentUsage()

    .detectWrongFragmentContainer() .detectSetUserVisibleHint() .build()
  19. detectFragmentReuse !" Повторное использование Fragment, который был удален из FragmentManager

    val firstFragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG_FIRST) !7 return fragmentManager.commit { remove(firstFragment) } fragmentManager.commit { !" Добавление Fragment, удалённого ранее add(R.id.fragment_container, firstFragment, FRAGMENT_TAG_FIRST) }
  20. detectFragmentTagUsage !" Использование тэга при добавление Fragment в XML <fragment

    android:name="dev.androidbroadcast.fragmentdemo.FirstFragment" android:tag="first" android:layout_width="match_parent" android:layout_height="match_parent" !"
  21. detectWrongFragmentContainer !" Неправильный layout-контейнер для Fragment <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:name="dev.androidbroadcast.fragmentdemo.FirstFragment"

    android:tag="first" !"
  22. detectWrongFragmentContainer !# Правильный layout-контейнер для Fragment <androidx.fragment.app.FragmentContainerView android:layout_width="match_parent" android:layout_height="match_parent" android:name="dev.androidbroadcast.fragmentdemo.FirstFragment"

    android:tag="first" !"
  23. detectSetUserVisibleHint !" userVisibleHint уже deprecated fragment.userVisibleHint = false

  24. detectRetainInstanceUsage !" retainInstance уже deprecated fragment.retainInstance = true if (fragment.retainInstance)

    { !!@ }
  25. detectTargetFragmentUsage !" setTargetFragment уже deprecated firstFragment.setTargetFragment(secondFragment, FRAGMENT_REEQUEST_CODE)

  26. Fragment Result API class FirstFragment : Fragment() { parentFragmentManager.setFragmentResultListener( FRAGMENT_REQUEST_KEY,

    viewLifecycleOwner ) { requestKey: String, result: Bundle !" } }
  27. Множественный Back Stack

  28. Добавление Fragment в Back Stack Back Stack

  29. Добавление Fragment в Back Stack supportFragmentManager.commit { replace( R.id.fragment_container, homeFragment,

    FRAGMENT_TAG_HOME ) addToBackStack(null) } Back Stack HomeFragment
  30. SavedState Back Stack

  31. !" Добавляем начальный Fragment supportFragmentManager.commit { setReorderingAllowed(true) replace<HomeFragment>(R.id.fragment_container) } SavedState

    Back Stack HomeFragment
  32. SavedState Back Stack HomeFragment

  33. supportFragmentManager.commit { setReorderingAllowed(true) replace<ProfileFragment>(R.id.fragment_container) addToBackStack("profile") } SavedState Back Stack HomeFragment

    ProZleFragment EditProZleFragment supportFragmentManager.commit { setReorderingAllowed(true) replace<EditProfileFragment>(R.id.fragment_container) addToBackStack("profile") }
  34. SavedState Back Stack HomeFragment ProZleFragment EditProZleFragment

  35. SavedState proZle Back Stack HomeFragment ProZleFragment EditProZleFragment supportFragmentManager.saveBackStack("profile")

  36. NotiZcationsFragment SavedState proZle Back Stack HomeFragment ProZleFragment EditProZleFragment supportFragmentManager.saveBackStack("profile") supportFragmentManager.commit

    { setReorderingAllowed(true) replace<NotificationsFragment>(R.id.fragment_container) addToBackStack("notifications") }
  37. SavedState proZle Back Stack HomeFragment ProZleFragment EditProZleFragment NotiZcationsFragment

  38. SavedState proZle supportFragmentManager.saveBackStack("notifications") Back Stack HomeFragment ProZleFragment EditProZleFragment notiZcations NotiZcationsFragment

  39. SavedState supportFragmentManager.saveBackStack("notifications") Back Stack HomeFragment ProZleFragment EditProZleFragment notiZcations NotiZcationsFragment supportFragmentManager.restoreBackStack("profile")

  40. SavedState Back Stack HomeFragment ProZleFragment EditProZleFragment notiZcations NotiZcationsFragment

  41. SavedState supportFragmentManager.clearBackStack("notifications") Back Stack HomeFragment ProZleFragment EditProZleFragment

  42. None
  43. Новые Android Lint проверки

  44. Новые проверки в Android Lint ! UseGetLayoutInflater Использование неправильного LayoutInflater

    в DialogFragment ! DialogFragmentCallbacksDetector Переопределение callback у Dialog, а не DialogFragment ! FragmentAddMenuProvider Использование неверного Lifecycle при использовании addMenuProvider ! DetachAndAttachFragmentInSameFragmentTransaction Выполнение attach и detach для одного и того же Fragment в рамках одной транзакции