【kotlin】超簡単なMVVMを実装してみた、③画面遷移、ViewModelに引数を追加する

# 実装内容
EditTextに文字を入力して「移動する」ボタンを押したら、画面遷移し、入力した文字が表示される。

遷移元の画面
![Screenshot_20230909_003404.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784089/1e3a2293-e62b-3a71-7772-b8a589ceb445.png)

遷移先の画面

![Screenshot_20230909_003417.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784089/58a4ae88-ef17-c202-0e87-e49defd0110d.png)

**[コード]**
**・イベントクラスの設定**
イベント通知用のクラス作成
下記のURL参照
https://github.com/google/iosched/blob/main/shared/src/main/java/com/google/samples/apps/iosched/shared/result/Event.kt
```kotlin:
open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // Allow external read but not write

    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }
    fun peekContent(): T = content
}


class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
    override fun onChanged(event: Event<T>?) {
        event?.getContentIfNotHandled()?.let { value ->
            onEventUnhandledContent(value)
        }
    }
}
```

**・遷移元のViewModelの設定**
```kotlin:
class MainViewModel : ViewModel(){
    
    private val _onMoveSubActivity: MutableLiveData<Event<String>> by lazy { MutableLiveData<Event<String>>()}
    val onMoveSubActivity: LiveData<Event<String>> = _onMoveSubActivity

    //　「移動する」をクリックしたときの処理
    fun onClickButton(text: String) {
        _onMoveSubActivity.value = Event(text)
    }
}
```

**・遷移元のViewの設定**
```kotlin:
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // viewBinding初期化
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        // viewModel初期化
        viewModel = ViewModelProvider(this)[MainViewModel::class.java]

        binding.button.setOnClickListener {
            viewModel.onClickButton(binding.editTextText.text.toString())
        }

        // 画面遷移の処理
        viewModel.onMoveSubActivity.observe(this, EventObserver {
            val intent = Intent(this, SubActivity::class.java)
            intent.putExtra(SubViewModel.SEND_MESSAGE, it)
            startActivity(intent)
        })
    }
}
```

**・遷移先のViewModelの設定**
```kotlin:
class SubViewModel(intent: Intent)  : ViewModel(){

    // ViewModelに引数を追加する設定
    class Factory constructor(
        private val intent: Intent
    ) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T =
            SubViewModel(intent) as T
    }

    companion object {
        const val SEND_MESSAGE = "SEND_MESSAGE"
    }

    private val _textViewStr: MutableLiveData<String> by lazy { MutableLiveData<String>("")}
    val textViewStr: LiveData<String> = _textViewStr

    // 起動時の処理
    init {
        _textViewStr.value = intent.getStringExtra(SEND_MESSAGE)
    }
}
```
**・遷移先のViewの設定**
```kotlin:
class SubActivity : AppCompatActivity() {

    private lateinit var binding: ActivitySubBinding
    private lateinit var viewModel: SubViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // viewBinding初期化
        binding = ActivitySubBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // viewModel初期化
        viewModel = ViewModelProvider(this, SubViewModel.Factory(intent))[SubViewModel::class.java]

        //  LiveDataを読み込み反映
        viewModel.textViewStr.observe(this, Observer {
            binding.textView.text = it
        })

    }

}
```