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?
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.
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”.
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.
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.
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) } }
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With