1
94

코틀린 ViewModel에서 setOnClickLisenter사용 방법 문의


RestActivity.kt


package com.example.internet_ex

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.lifecycle.*
import kotlinx.coroutines.launch
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path
import java.lang.StringBuilder

data class Owner(val login: String)
data class Repo(val name: String, val owner: Owner, val url: String)
data class Contributor(val login: String, val contributions: Int)

interface RestApi {
    @GET("users/{user}/repos")
    suspend fun listRepos(@Path("user") user: String): List<Repo>

    @GET("/repos/{owner}/{repo}/contributors")
    suspend fun contributors(
        @Path("owner") owner: String,
        @Path("repo") repo: String
    ): List<Contributor>
}

class MyViewModel : ViewModel() {
    private val baseURL = "https://api.github.com/"
    private lateinit var api: RestApi
    val userName = MutableLiveData<String>()

    val response = MutableLiveData<String>()


    init {
        retrofitInit()
        refreshData()
    }

    fun refreshData() {
        viewModelScope.launch {
            try {
                val repos = api.listRepos(userName.toString())
                response.value = StringBuilder().apply {
                    repos.forEach {
                        append(it.name)
                        append(" - ")
                        append(it.owner.login)
                        append("\n")
                    }
                }.toString()
            } catch (e: Exception) {
                response.value = "Failed to connect to the server"
            }
        }
    }

    private fun retrofitInit() {
        val retrofit = Retrofit.Builder()
            .baseUrl(baseURL)
            .addConverterFactory(MoshiConverterFactory.create())

            .build()

        api = retrofit.create(RestApi::class.java)
    }
}


class RestActivity : AppCompatActivity() {
    private lateinit var myViewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_rest)

        myViewModel = ViewModelProvider(this).get(MyViewModel::class.java)
//        문제가 되는 부분
        myViewModel.userName.observe(this) {
            findViewById<Button>(R.id.queryBtn).setOnClickListener {
                myViewModel.userName.value = findViewById<Button>(R.id.nameText).toString()
                myViewModel.refreshData()
            }
        }
        myViewModel.response.observe(this) {
            findViewById<TextView>(R.id.textResponse).text = it
            findViewById<Button>(R.id.queryBtn).setOnClickListener {
            }
        }
    }
}

뷰모델에 있는 userName을 queryBtn을 눌렀을 때 바꾸고 싶어서 문제가 되는 부분이라고 주석 처리 해둔 곳을 만들었는데 동작을 안합니다. 왜 안되는 걸까요?ㅠㅠ

0
  • 답변 1

  • HSYE
    214
    2021-10-14 12:09:22
    myViewModel.userName.observe(this) {
                findViewById<Button>(R.id.queryBtn).setOnClickListener {
                    myViewModel.userName.value = findViewById<Button>(R.id.nameText).toString()
                    myViewModel.refreshData()
                }
            }

    부분을 보시면 userName의 변경이 관찰된 후 queryBtn에 리스너를 등록하고 있습니다.

    즉 userName의 변경이 없다면 queryBtn에 등록된 리스너가 없기 때문에 아무리 버튼을 클릭해도 동작하지 않습니다.

  • 로그인을 하시면 답변을 등록할 수 있습니다.