Android Architecture ComponentsのViewModelとHolderFragmentとActivity-Fragment間通信と。 - visible trueを書いたあと、
ああ、ViewModelでActivity-Fragment間通信するやつ、FragmentDialogでやるとよかったのか
— 八木 (@sys1yagi) August 23, 2017
ということで試したら行けました。
Source
https://github.com/sys1yagi/aac-viewmodel-with/tree/master/fragment-dialog
MainViewModel
コールバック的な値をLiveDataで定義する。今回はUnitにしてるけどなんでもよさそう。
class MainViewModel : ViewModel() { val dialogOk = MutableLiveData<Unit>() val dialogCancel = MutableLiveData<Unit>() }
HelloDialog
DialogでMainViewModelを取り出して対応するアクションの値を更新する。
class HelloDialog : DialogFragment() { companion object { fun newInstance() = HelloDialog() } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(activity) val viewModel = ViewModelProviders.of(activity).get(MainViewModel::class.java) builder.setMessage("Hello") .setPositiveButton("Yes", { _, _ -> viewModel.dialogOk.value = Unit }) .setNegativeButton("Cancel", { _, _ -> viewModel.dialogCancel.value = Unit }) return builder.create() } }
MainActivity
DialogのためのLiveDataはonCreateでobserveしないと、process killレベルのActivity破棄が起こった時にはずれてしまうので注意。
class MainActivity : AppCompatActivity(), LifecycleRegistryOwner { override fun getLifecycle() = registry val registry = LifecycleRegistry(this) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById<Button>(R.id.button).setOnClickListener { HelloDialog.newInstance().show(supportFragmentManager, "hello") } val viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java) viewModel.dialogOk.observe(this, Observer { Toast.makeText(this, "OK", Toast.LENGTH_SHORT).show() }) viewModel.dialogCancel.observe(this, Observer { Toast.makeText(this, "Cancel", Toast.LENGTH_SHORT).show() }) } }
シュッ
雑感
悪くない。