我想在与LiveData
一起使用DataBinding时更改UI。但是随着LiveData
的变化,它并没有反映UI的变化。
MainViewModel.java
public class MainViewModel extends AndroidViewModel {
/**
* Boolean variable to see whether user is ClockedIn or ClockedOut
*/
public MutableLiveData<Boolean> isClockedIn;
public MainViewModel(Application application) {
super(application);
isClockedIn = new MutableLiveData<>();
//...
calculateClockedInOrNot(PreferencesManager.getString(mContext,PreferencesManager.CLOCK_STATUS_KEY));
}
/**
* An utility function to calculate whether user is clocked in or clocked out,
* this function is also called within this ViewModel after an api hit
*
* if string == "CLOCKED_OUT" or string == "mobileEventType.CLOCK_OUT" => user is clocked out
* else user is clocked in
*/
private void calculateClockedInOrNot(String string) {
if (string.equals("CLOCKED_OUT") || string.equals("mobileEventType.CLOCK_OUT")) {
//user is clocked out
isClockedIn.setValue(false);
} else {
//user is clocked in
isClockedIn.setValue(true);
}
}
//getter function
public MutableLiveData<Boolean> isClockedIn() {
return isClockedIn;
}
//other function left for brevity
}
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Obtain the ViewModel component.
mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
// Inflate view and obtain an instance of the binding class.
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
// Assign the component to a property in the binding class.
binding.setData(mainViewModel);
}
activity_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="com.app.bidunity.viewmodel.MainViewModel" />
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="@dimen/img_hight_location"
android:adjustViewBounds="true"
android:src="@{data.clockedIn ? @drawable/ic_location_on : @drawable/ic_location_off}"/>
<!--Other view left for brevity-->
</LinearLayout>
</layout>
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.app.bidunity"
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}
dependencies {
def arch_version = "2.0.0-rc01"
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
//material library
implementation 'com.google.android.material:material:1.0.0'
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$arch_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
}
我正在将 android studio 3.3 Canary 11 与 gradle 4.10.1 和onclick
一起使用,并在视图模型中使用了数据绑定,但是即使更改了{{ 1}} isClockedIn
不变,它是可绘制的。我已经尝试了所有方法,甚至调试了ImageView
是否在运行过程中进行了更改,是的,它的值正在更改
答案 0 :(得分:6)
您需要将您的 isClockedIn
变量设置为可观察字段,
因此从以下位置替换它
public boolean isClockedIn = false;
到
public ObservableBoolean isClockedIn = new ObservableBoolean();
注意:还请确保xml具有与 ViewModel
中相同的变量名引用here
编辑:
如果您不想进行 ObservableField ,则需要进行其他一些更改。
尽管有 ObservableField ,您仍需要将其可观察范围扩展为 BaseObservable
,并且在 livedata 中需要布尔值更改后调用notifyPropertyChanged(BR.isClockedIn);
。
如果您想使用LiveData作为观察者,首先是提供绑定的生命周期
// Specify the current activity as the lifecycle owner (in your activity/fragment).
binding.setLifecycleOwner(this);
在您的ViewModel中,使用LiveData对象观察更改并在其上应用Transformation:
MutableLiveData<Boolean> dataToBeObserve = new MutableLiveData<>();
LiveData booleanDataChange = Transformations.map(dataToBeObserve, dataToBeObserve-> dataToBeObserve.value);
现在,使用此 booleanDataChange
来xml并更改您的MutableLiveData值以观察数据更改事件。
注意:您可以将相同的LiveData用于更改事件,只需要将定义拆分为构造函数调用即可。
答案 1 :(得分:0)
尝试执行以下步骤以通过cleartool findmerge -all -fver /main/release2/LATEST -print
cleartool findmerge -all -fver /main/release2/10 -print
cleartool findmerge filename -fver /main/release2/LATEST -print
cleartool findmerge filename -fver /main/release2/myprivateview/0 -print
实现:
首先,在您的LiveData
MainViewModel
第二,在您的public MutableLiveData<Boolean> checked;
中,也输入:
MainViewModel
第三,将此方法修改为:
public MutableLiveData<Boolean> isChecked() {
if (checked == null) {
checked = new MutableLiveData<>();
}
return checked;
}
最后,在您的private void calculateClockedInOrNot(String string) {
if (string.equals("CLOCKED_OUT") || string.equals("mobileEventType.CLOCK_OUT")) {
//user is clocked out
checked.setValue(false);
} else {
//user is clocked in
checked.setValue(true);
}
}
中输入:
onCreate()
注意:从ImageView中删除此loginViewModel.isChecked().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean checked) {
if(checked) {
findViewById(R.id.imageView).setDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.location_on));
}
else {
findViewById(R.id.imageView).setDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.location_off));
}
}
});
。
就是这样。我认为这应该有所帮助。