Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin - idiomatic way to create a Fragment newInstance pattern

The best practice on Android for creating a Fragment is to use a static factory method and pass arguments in a Bundle via setArguments().

In Java, this is done something like:

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;     } } 

In Kotlin this converts to:

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         }     } } 

This makes sense to support interop with Java so it can still be called via MyFragment.newInstance(...), but is there a more idiomatic way to do this in Kotlin if we don't need to worry about Java interop?

like image 209
triad Avatar asked Nov 03 '17 21:11

triad


People also ask

How do I create a fragment object in Kotlin?

The best practice on Android for creating a Fragment is to use a static factory method and pass arguments in a Bundle via setArguments() . This makes sense to support interop with Java so it can still be called via MyFragment.

How do I create a new instance of fragment in Kotlin?

The correct way to instantiate a new fragment and passing values to it, is by creating a bundle, setting arguments on this bundle and then passing it to our fragment. Inside the fragment we then retrieve this bundle and get the values out of it. A clean way to do this is by creating a so called “factory method”.

What is a kotlin companion object?

Answer: Companion object is not a Singleton object or Pattern in Kotlin – It's primarily used to define class level variables and methods called static variables. This is common across all instances of the class.

What is called when you create an instance of a class Kotlin?

createInstance(): T. Creates a new instance of the class, calling a constructor which either has no parameters or all parameters of which are optional (see KParameter.


2 Answers

I like to do it this way:

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: with KotlinX extensions, you can also do this

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)     } } 
like image 99
Francesc Avatar answered Sep 24 '22 23:09

Francesc


inline fun <reified T : Fragment>     newFragmentInstance(vararg params: Pair<String, Any>) =     T::class.java.newInstance().apply {         arguments = bundleOf(*params)     }` 

So it is used like that:

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

Credit

bundleOf() can be taken from Anko

like image 42
Dmide Avatar answered Sep 23 '22 23:09

Dmide