Api 调用 mvvm Android
Api Call in mvvm Android
我是 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()
}
}
}
这是我的主要活动。当我在我的视图模型中调用 api 时,测试始终为 null,它应该是 10000 或其他一些数字。我认为 createCode 函数在 OnResponse 或 OnFailure 被触发之前完成。但我不知道该怎么做,我想使用 mvvm。
我想,您的问题是因为您在 activity 中观察了 LiveData 的一个对象,但是当您从 api 收到结果时,您只需将此对象替换为新的 LiveData。您应该等待结果并将其写入您的 ViewModel 中已创建的 LiveData。使用 MediatorLiveData 是可能的。像这样:
val monthData = MediatorLiveData<MonthData>() /// livedata i subscribed in view
这是我在视图模型中的 "api call"。这是主要的魔法。我将视图模型的实时数据订阅到 "api call" 的结果,并将数据从那里传递到此实时数据:
fun loadMonthEvents() {
monthData.addSource(useCase.getCalendarEvents()) {
monthData.value = it
}
}
在我的例子中,我在 RxJava 上的 repo,我将它转换为这样的实时数据(用例):
fun getCalendarEvents(): LiveData<MonthData?> {
val result = mutableLiveDataOf<MonthData?>()
appointmentsRepository.getAppointmentsIn().subscribe { data ->
result.value = data
}
return result
}
希望对你有所帮助。无论如何,如果您还有问题,请发表评论:)
我是 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()
}
}
}
这是我的主要活动。当我在我的视图模型中调用 api 时,测试始终为 null,它应该是 10000 或其他一些数字。我认为 createCode 函数在 OnResponse 或 OnFailure 被触发之前完成。但我不知道该怎么做,我想使用 mvvm。
我想,您的问题是因为您在 activity 中观察了 LiveData 的一个对象,但是当您从 api 收到结果时,您只需将此对象替换为新的 LiveData。您应该等待结果并将其写入您的 ViewModel 中已创建的 LiveData。使用 MediatorLiveData 是可能的。像这样:
val monthData = MediatorLiveData<MonthData>() /// livedata i subscribed in view
这是我在视图模型中的 "api call"。这是主要的魔法。我将视图模型的实时数据订阅到 "api call" 的结果,并将数据从那里传递到此实时数据:
fun loadMonthEvents() {
monthData.addSource(useCase.getCalendarEvents()) {
monthData.value = it
}
}
在我的例子中,我在 RxJava 上的 repo,我将它转换为这样的实时数据(用例):
fun getCalendarEvents(): LiveData<MonthData?> {
val result = mutableLiveDataOf<MonthData?>()
appointmentsRepository.getAppointmentsIn().subscribe { data ->
result.value = data
}
return result
}
希望对你有所帮助。无论如何,如果您还有问题,请发表评论:)