データバインディングを使用して、1つの単純なビューの非表示/表示を実現しようとしています。 API呼び出しがあり、API呼び出しの実行中に1つのプログレスバーを表示する必要があります。応答を受け取ったら、この進行状況を閉じてデータを表示する必要があります。データバインディングを使用して、プログレスバーの表示を動的に変更しようとしました。しかし、何も起こりません。プログレスバーの可視性は、バインディング変数に従って初めて設定されます。バインディング変数を更新しても、動的には更新されません。
以下は同じの私のサンプルコードです
アクティビティ:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
final ViewModel viewmodel = new ViewModel();
binding.setViewmodel(viewmodel);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
loadData(viewmodel);
}
});
}
private void loadData(final ViewModel viewmodel) {
viewmodel.setLoading(true);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Loading finished");
viewmodel.setLoading(false);
}
}, 2000);
}
}
ViewModel:
import Android.databinding.BaseObservable;
import Android.databinding.Bindable;
public class ViewModel extends BaseObservable {
private boolean isLoading;
private String data;
@Bindable
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Bindable
public boolean isLoading() {
return isLoading;
}
public void setLoading(boolean loading) {
isLoading = loading;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools">
<data>
<import type="Android.view.View"/>
<variable name="viewmodel" type="com.test.databindnig.ViewModel"/>
</data>
<LinearLayout
Android:id="@+id/activity_main"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:gravity="center_horizontal"
Android:orientation="vertical"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.test.databindnig.MainActivity">
<ProgressBar
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
Android:visibility="@{viewmodel.isLoading ? View.VISIBLE : View.GONE}"/>
<TextView
Android:id="@+id/text"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@{viewmodel.data}"
Android:visibility="@{viewmodel.isLoading ? View.GONE : View.VISIBLE}"/>
<Button
Android:id="@+id/btn"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
Android:text="Load data"/>
</LinearLayout>
</layout>
また、アプリのbuild.gradleにもあります
dataBinding {
enabled = true
}
ここに何が欠けていますか?なぜうまくいかないのですか?前もって感謝します..
プロパティ値が変更されたことを通知する必要があります。これを試してください
public void setLoading(boolean loading) {
isLoading = loading;
notifyPropertyChanged(BR._all);
}
または、単一の変数についてのみ通知する場合は、BR.propertyNameを使用します
notifyPropertyChanged(BR.loading);
notifyPropertyChanged(BR._all);
を使用すると、すべてのオブザーバブルに不必要に通知されることを明確にしたいと思います。
変更されたアイテムのみを通知するには、代わりにnotifyPropertyChanged(BR.field);
を使用する必要があります。
model.setLoading(true)
が必要な場合。この分野からの関連する見解を屈折させます。
注意アクセサには@Bindable
属性の注釈を付ける必要があります。それ以外の場合、BR
クラスにはフィールド名がありません。
@Bindable
public boolean isLoading() {
return isLoading;
}
public void setLoading(boolean isLoading ) {
this.isLoading = isLoading ;
notifyPropertyChanged(BR.isLoading );
}
追加
<import type="Android.view.View" />
XMlファイルの結果ソリューションの上に次のようになります
<data>
<import type="Android.view.View" />
<variable
name="obj"
type="com.you.modal.class" />
</data>
<import type="Android.view.View" />