web-dev-qa-db-ja.com

Androidデータバインディングを使用してビューの可視性を動的に変更する方法

データバインディングを使用して、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
}

ここに何が欠けていますか?なぜうまくいかないのですか?前もって感謝します..

8
user4489210

プロパティ値が変更されたことを通知する必要があります。これを試してください

public void setLoading(boolean loading) {
    isLoading = loading;
    notifyPropertyChanged(BR._all);
}

または、単一の変数についてのみ通知する場合は、BR.propertyNameを使用します

notifyPropertyChanged(BR.loading);
7
Ravi

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 );
}
0
Khemraj

追加 <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" />
0
rinkesh