Fragment
を作成するためのAndroidのベストプラクティスは、静的ファクトリメソッドを使用し、setArguments()
経由でBundle
に引数を渡すことです。
Javaでは、これは次のように行われます。
_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;
}
}
_
Kotlinでは、これは次のように変換されます。
_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
}
}
}
_
これは、Javaとの相互運用をサポートするのが理にかなっているので、MyFragment.newInstance(...)
を介して呼び出すことができますが、Kotlinでこれを行う必要のないより慣用的な方法はありますか? Java interop?
私はこのようにしたい:
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)
}
}
}
編集:KotlinX拡張機能を使用すると、これも実行できます
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)
}
}
パーティーに遅れましたが、慣用的には次のようなものになるはずです。
private const val FOO = "foo"
private const val BAR = "bar"
class MyFragment : Fragment() {
companion object {
fun newInstance(foo: Int, bar: String) = MyFragment().withArgs {
putInt(FOO, foo)
putString(BAR, bar)
}
}
}
このような拡張子を使用すると:
inline fun <T : Fragment> T.withArgs(argsBuilder: Bundle.() -> Unit): T =
this.apply {
arguments = Bundle().apply(argsBuilder)
}
または
companion object {
fun newInstance(foo: Int, bar: String) = MyFragment().apply {
arguments = bundleOf(
FOO to foo,
BAR to bar
)
}
}
重要なのは、プライベート定数がコンパニオンオブジェクトの一部であってはならないということです。
これを行う別の方法I ここにあります
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
}
...
}
...
}
Kotlinパッケージレベルの関数
「静的」メソッドの代わりにパッケージレベル関数を使用することをkotlinが言うことについてはどうですか
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()
}
}