Android VMTV中的Api呼叫

时间:2019-05-18 21:40:48

标签: android mvvm kotlin android-mvvm

我是mvvm的新手,我一直在尝试使用改造在mvvm中的kotlin中调用api。 这是我的xml

<TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView" app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="84dp" app:layout_constraintTop_toTopOf="parent"/>
<Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button" app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintHorizontal_bias="0.498" app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="332dp" app:layout_constraintTop_toBottomOf="@+id/textView"
        android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent"/>

您可以看到我只有两个元素。一个用于调用API的按钮,然后显示该调用的结果代码(无论是200还是其他)。

class testViewModel: ViewModel() {
    var testInput :MutableLiveData<Int> = MutableLiveData(1)
    var test :LiveData<Int> = testInput
    fun clicked(){


        test = API_Repository.createCode()
        println(test.value.toString())

    }
}

这是我的视图模型。

fun createCode(): LiveData<Int> {
    var sendUser = CreateCodeUserClass()
    sendUser.setUsername("09360767928")
    var data = MutableLiveData<Int>()
    my_API_Interface!!.CreateCode(sendUser).enqueue(object : retrofit2.Callback<Void> {
        override fun onFailure(call: Call<Void>, t: Throwable) {
            data.value = 10000
            println(data.value.toString())
        }

        override fun onResponse(call: Call<Void>, response: Response<Void>) {
            data.value = response.code()

        }

    })
    return data
}

这是我的API调用

class MainActivity : AppCompatActivity() {

    public var viewModel = testViewModel()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewModel = ViewModelProviders.of(this).get(testViewModel::class.java)
            viewModel.test!!.observe(this, Observer { data ->
                print(data.toString())
                textView.text = data.toString()
            })

        button.setOnClickListener {
            viewModel.clicked()
        }
    }
}

这是我的mainActivity。当我在视图模型中调用api时,test始终为null,应为10000或其他一些数字。我认为createCode函数在触发OnResponse或OnFailure之前完成。但是我不知道该怎么办,我想使用mvvm。

1 个答案:

答案 0 :(得分:0)

我猜,您的问题是因为您在活动中观察到LiveData的一个对象,但是当您从api收到结果时,只需将该对象替换为新的LiveData。您应该等待结果并将其写入ViewModel中已创建的LiveData中。 MediatorLiveData是可能的。像这样:

val monthData = MediatorLiveData<MonthData>() /// livedata i subscribed in view

这是我在viewmodel中的“ api调用”。这是主要的魔术。我将viewmodel的livedata订阅到我的“ api调用”的结果中,并将数据从那里传递给此livedata:

fun loadMonthEvents() {
    monthData.addSource(useCase.getCalendarEvents()) {
        monthData.value = it
    }
}

就我而言,是我在RxJava上的仓库,我将其转换为livedata,就像这样(UseCase):

fun getCalendarEvents(): LiveData<MonthData?> {
    val result = mutableLiveDataOf<MonthData?>()

    appointmentsRepository.getAppointmentsIn().subscribe { data ->
        result.value = data
    }

    return result
}

希望,它将为您提供帮助。无论如何,如果您还有问题,请发表评论:)