web-dev-qa-db-fra.com

Kotlin - moyen idiomatique de créer un motif Fragment newInstance

La meilleure pratique sur Android pour créer une Fragment consiste à utiliser une méthode de fabrique statique et à transmettre des arguments dans une Bundle via setArguments()

En Java, cela se fait de la manière suivante:

public class MyFragment extends Fragment {
    static MyFragment newInstance(int foo) {
        Bundle args = new Bundle();
        args.putInt("foo", foo);
        MyFragment fragment = new MyFragment();
        fragment.setArguments(args);
        return fragment;
    }
}

En Kotlin, cela se convertit en:

class MyFragment : Fragment() {
    companion object {
       fun newInstance(foo: Int): MyFragment {
            val args = Bundle()
            args.putInt("foo", foo)
            val fragment = MyFragment()
            fragment.arguments = args
            return fragment
        }
    }
}

Cela a du sens de prendre en charge l'interopérabilité avec Java afin qu'il puisse toujours être appelé via MyFragment.newInstance(...), mais existe-t-il une méthode plus idiomatique de le faire dans Kotlin si nous n'avons pas à nous soucier de l'interopérabilité Java?

11
triad

J'aime le faire de cette façon:

companion object {
    private const val MY_BOOLEAN = "my_boolean"
    private const val MY_INT = "my_int"

    fun newInstance(aBoolean: Boolean, anInt: Int) = MyFragment().apply {
        arguments = Bundle(2).apply {
            putBoolean(MY_BOOLEAN, aBoolean)
            putInt(MY_INT, anInt)
        }
    }
}

Edit: avec les extensions KotlinX, vous pouvez aussi le faire

companion object {
    private const val MY_BOOLEAN = "my_boolean"
    private const val MY_INT = "my_int"

    fun newInstance(aBoolean: Boolean, anInt: Int) = MyFragment().apply {
        arguments = bundleOf(
            MY_BOOLEAN to aBoolean,
            MY_INT to anInt)
    }
}
27
Francesc
inline fun <reified T : Fragment>
    newFragmentInstance(vararg params: Pair<String, Any>) =
    T::class.Java.newInstance().apply {
        arguments = bundleOf(*params)
    }`

Donc, il est utilisé comme ça:

val fragment = newFragmentInstance<YourFragment>("key" to value)

Crédit

bundleOf() peut être extrait de Anko

4
Dmide

Une autre façon de le faire je trouvé ici

class MyFragment: Fragment(){
  companion object{
    private val ARG_CAUGHT = "myFragment_caught"

    fun newInstance(caught: Pokemon):MyFragment{
      val args: Bundle = Bundle()
      args.putSerializable(ARG_CAUGHT, caught)
      val fragment = MyFragment()
      fragment.arguments = args
      return fragment
    }
    ...
  }
  ...
}
1
Xar E Ahmer

Fonction au niveau du paquet Kotlin

Qu'en est-il de cette kotlin dit d'utiliser la fonction de paquet au lieu de la méthode "statique"

MyFragment.kt

class MyFragment : Fragment() {

    .....

}

fun MyFragmentNewInstance(): MyFragment {
    return MyFragment()
}

MyActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (supportFragmentManager.findFragmentById(R.id.fragmentContainer) == null) {
        supportFragmentManager.beginTransaction()
            .add(R.id.fragmentContainer, MyFragmentNewInstance())
            .commit()
    }
}
0
Irving Lóp