0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2023-09-10

実装内容

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

遷移元の画面
Screenshot_20230909_003404.png

遷移先の画面

Screenshot_20230909_003417.png

[コード]
・イベントクラスの設定
イベント通知用のクラス作成
下記のURL参照
https://github.com/google/iosched/blob/main/shared/src/main/java/com/google/samples/apps/iosched/shared/result/Event.kt

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の設定

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の設定

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の設定

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の設定

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

    }

}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?