Upgrade to Pro — share decks privately, control downloads, hide ads and more …

最新のFragment事情 / Fragment new features

star_zero
November 21, 2019

最新のFragment事情 / Fragment new features

star_zero

November 21, 2019
Tweet

More Decks by star_zero

Other Decks in Programming

Transcript

  1. 最新のFragment事情
    Android感謝祭
    2019/11/21

    View Slide

  2. About me
    •Kenji Abe
    •クックパッド株式会社
    •Google Developers Expert for Android
    •Twitter: @STAR_ZERO

    View Slide

  3. Update Fragment

    View Slide

  4. ⚠今回の環境⚠
    •Fragment 1.2.0 rc-02
    ‣ 2019/11/21時点の最新

    View Slide

  5. Constructor with LayoutId

    View Slide

  6. Constructor with LayoutId
    •コンストラクタにLayoutIdを渡せるようになった
    •DataBinding/ViewBindingは非対応
    class SampleFragment : Fragment(R.layout.fragment_sample)

    View Slide

  7. Constructor with LayoutId
    https://developer.android.com/reference/androidx/fragment/app/Fragment.html

    View Slide

  8. FragmentContainerView

    View Slide

  9. FragmentContainerView
    •これからはFrameLayoutではなくコチラが推奨
    •アニメーションのz-orderなどのバグがあった
    •https://issuetracker.google.com/issues/37036000

    View Slide

  10. FragmentContainerView
    android:id="@+id/container"
    android:name="com.example.SampleFragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

    View Slide

  11. OnBackPressedDispatcher

    View Slide

  12. OnBackPressedDispatcher
    •Fragmentでバックキーの制御が可能になった
    •Lifecycleによってコールバックの追加、削除が簡単
    •コールバックの有効、無効の切り替えも可能

    View Slide

  13. OnBackPressedDispatcher
    class SampleFragment : Fragment() {
    private val callback = object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
    // バックキーが押されたとき...
    }
    }
    override fun onAttach(context: Context) {
    super.onAttach(context)
    requireActivity().onBackPressedDispatcher
    .addCallback(this, callback)
    }
    }

    View Slide

  14. OnBackPressedDispatcher
    class SampleFragment : Fragment() {
    // ...
    fun someFunction() {
    callback.isEnabled = false
    requireActivity().onBackPressedDispatcher.onBackPressed()
    }
    }

    View Slide

  15. OnBackPressedDispatcher
    class MainActivity : AppCompatActivity() {
    override fun onBackPressed() {
    // FragmentのhandleOnBackPressedの後に呼び出される
    if (onBackPressedDispatcher.hasEnabledCallbacks()) {
    // Fragmentのバックキー制御が有効
    } else {
    // Fragmentのバックキー制御が無効
    }
    }
    }

    View Slide

  16. FragmentFactory

    View Slide

  17. FragmentFactory
    •Fragmentの生成を行うクラス
    •Fragmentのコンストラクタに引数が渡せるようになる
    ‣ コンストラクタインジェクションが可能
    •引数なしのコンストラクタ不要
    •FragmentScenarioでMock

    View Slide

  18. FragmentFactory
    class SampleFactory: FragmentFactory() {
    override fun instantiate(
    classLoader: ClassLoader,
    className: String
    ): Fragment {
    return when (className) {
    SampleFragment::class.java.name -> SampleFragment("ABC")
    else -> super.instantiate(classLoader, className)
    }
    }
    }

    View Slide

  19. FragmentFactory
    class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    supportFragmentManager.fragmentFactory = SampleFactory()
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    // fragment-ktx
    supportFragmentManager.commit {
    add(R.id.container)
    }
    }
    }

    View Slide

  20. FragmentFactory
    @RunWith(AndroidJUnit4::class)
    class SampleFragmentTest {
    @Test
    fun textSample() {
    val mockFactory = MockFactory()
    val scenario = launchFragmentInContainer(
    factory = mockFactory
    )
    onView(withId(R.id.text)).check(matches(withText("Hello World!")))
    }
    }

    View Slide

  21. FragmentFactory
    •Daggerで使うには?
    ‣ https://satoshun.github.io/2018/11/android_all_inject_ctor/

    View Slide

  22. RESUME_ONLY_CURRENT_FRAGMENT

    View Slide

  23. RESUME_ONLY_CURRENT_FRAGMENT
    •ViewPagerでonResumeが呼ばれるタイミングが変わる
    ‣ これまでは表示されてなくてもonResumeが呼ばれてた
    ‣ 表示されてるFragmentのonResumeのみが呼ばれる
    •setUserVisibleHintはDeprecated

    View Slide

  24. RESUME_ONLY_CURRENT_FRAGMENT
    class SampleAdapter(fm: FragmentManager) :
    FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
    // 以前の挙動にしたい場合は BEHAVIOR_SET_USER_VISIBLE_HINT
    override fun getItem(position: Int): Fragment {
    // ...
    }
    override fun getCount(): Int {
    // ...
    }
    }

    View Slide

  25. fragment-ktx

    View Slide

  26. fragment-ktx
    supportFragmentManager.commit {
    add(R.id.container)
    }
    val viewModel: SampleViewModel by viewModels()
    val viewModel: SampleViewModel by activityViewModels()
    val viewModel: SampleViewModel by viewModels { viewModelFactory }

    View Slide

  27. lint

    View Slide

  28. lint

    View Slide

  29. lint

    View Slide

  30. 今後のFragment

    View Slide

  31. 今後のFragment
    https://www.youtube.com/watch?v=RS1IACnZLy4

    View Slide

  32. 今後のFragment
    •Multiple Back Stacks
    •Fragmentの戻り値
    •Lifecycleの改善

    View Slide

  33. ありがとうございました

    View Slide