gpt4 book ai didi

java - Observable 数据绑定(bind) Observable 与 LiveData 在配置更改时具有不同的结果

转载 作者:行者123 更新时间:2023-12-02 09:07:10 24 4
gpt4 key购买 nike

我正在测试 DataBinding 的行为当涉及到使用 LiveData 时可以观察到与 ObservableInt .

我有一个简单的布局,其中有一个按钮可以触发 LiveData 的计数器& ObservableInt我存储在 ViewModel 中的变量,我使用 BindingAdapter 更新它们的值

两者LiveData & ObservableInt变量正常计数;但是当设备配置发生更改(我的测试的屏幕旋转)时,ObservableInt尽管 LiveData 会随着按钮点击而计数。驳回一两项罪名。

下面的gif将说明更多

我的问题是如何解决这个问题?我主要需要一个LiveData进一步Transformations

布局

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

<data>

<variable
name="viewmodel"
type="com.example.android.databindingobservableintlivedata.MyViewModel" />

</data>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">

<TextView
android:id="@+id/observableint_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ObservableInt: " />

<TextView
android:id="@+id/observableint_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
app:textValueForObservableInt="@{viewmodel.countObservableInt}" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center">

<TextView
android:id="@+id/livedata_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LiveData: " />

<TextView
android:id="@+id/livedata_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
app:textValueForLiveData="@{viewmodel.countLiveData}" />
</LinearLayout>

<Button
android:id="@+id/btn_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="16dp"
android:onClick="@{() -> viewmodel.onCount()}"
android:text="Count" />


</LinearLayout>
</layout>

Activity

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ActivityMainBinding mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
MyViewModel viewModel = ViewModelProviders.of(this).get(MyViewModel.class);

mBinding.setViewmodel(viewModel);
mBinding.setLifecycleOwner(this);

}
}

View 模型

public class MyViewModel extends ViewModel {

public MutableLiveData<Integer> countLiveData = new MutableLiveData<>(0);
public ObservableInt countObservableInt = new ObservableInt(0);

public void onCount() {
countObservableInt.set(countObservableInt.get() + 1);
int value = countLiveData.getValue() == null ? 0 : countLiveData.getValue();
countLiveData.postValue(value + 1);
}

}

绑定(bind)适配器

public class BindingAdapters {

@BindingAdapter("textValueForObservableInt")
public static void bindObservableIntInText(TextView text, ObservableInt value) {
text.setText(String.valueOf(value.get()));
}

@BindingAdapter("textValueForLiveData")
public static void bindLiveDataIntegerInText(TextView text, MutableLiveData<Integer> value) {
text.setText(String.valueOf(value.getValue()));
}

}

最佳答案

Post value LiveData:

基本上,此方法表明,为 LiveData 提供的任何值都可以/应该从后台线程调用(主线程除外) 将反射(reflect)在更新后的主线程上值。

这意味着,如果您连续两次调用 LiveData 关于 postValue() 的内容,那么只会发送最后一个值!

在您的情况下,如果对此方法的调用过于频繁,countLiveData.postValue(value + 1) 此行会影响值的后增量,如果仅更新最后一个值,而不更新连续值。

Set Value LiveData:

此方法要求必须从主线程进行调用,无论您进行了多少次调用,每次都会反射(reflect)/更新结果 UI。任何中间调用都不会被丢弃。

TL;DR

如果您必须从后台线程更新/设置值,请使用 postValue() 方法,否则在主线程上使用 setValue()

<小时/>

It takes a while for device rotation when I have continuous hits on the button, and suddenly rotate the device.

原因是,当您在旋转设备之前在主线程上调用 setValue() 时,每次调用都必须连续更新 UI,从而导致旋转内容延迟(在配置更改之前保留 UI 更新)发生)。这就是为什么在所有 setValue() 调用完成 UI 更新之前它会滞后/延迟旋转(在您的特定情况下,这一行是:app:textValueForLiveData="@{viewmodel.countLiveData}")。

关于java - Observable 数据绑定(bind) Observable 与 LiveData 在配置更改时具有不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59718657/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com