首页 > 解决方案 > 如何在 Android viewModels 中使用 setOnClickLisenter?

问题描述

休息活动

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)
//        problem
        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 {
            }
        }
    }
}

活动休息

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".RestActivity">

    <TextView
        android:id="@+id/textResponse"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/queryBtn" />

    <Button
        android:id="@+id/queryBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Query"
        app:layout_constraintStart_toEndOf="@+id/nameText"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/nameText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
**activity_rest.xml**

我做了一个地方,我评论说这是一个问题,因为我想userNameViewModel按下 时更改queryBtn,但它没有用。我想LiveData (userName)使用命令更改 ViewModel 中的setOnClickLisenter,但我无法弄清楚。如果您能告诉我要另外学习什么,我将不胜感激。

标签: javaandroidkotlinmvvmviewmodel

解决方案


移动这个外部观察者块

findViewById<Button>(R.id.queryBtn).setOnClickListener { 
              myViewModel.userName.value = findViewById<EditText>(R.id.nameText).getText().toString()
}

在观察者块内部,当用户字符串更新时,调用刷新数据

myViewModel.userName.observe(this) {
      myViewModel.refreshData()
  }

onClickListenerresponse观察者方块中移除。


推荐阅读