【问题标题】:How to dynamically change view visibility using android data binding如何使用 android 数据绑定动态更改视图可见性
【发布时间】:2016-11-29 05:59:10
【问题描述】:

我正在尝试使用数据绑定实现一个简单的视图隐藏/显示。我有一个 api 调用,我必须在 api 调用进行时显示一个进度条。一旦我得到响应,就必须关闭这个进度并显示数据。我尝试使用数据绑定动态更改进度条的可见性。但什么也没有发生。仅第一次根据绑定变量设置进度条可见性。当我更新绑定变量时,它不会动态更新。

以下是我的示例代码

活动:

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

视图模型:

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
}

这里缺少什么?为什么它不起作用?提前谢谢..

【问题讨论】:

    标签: android android-databinding


    【解决方案1】:

    你需要通知你的属性值改变了,试试这个

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

    或者如果您只想针对单个变量通知它,请使用 BR.propertyName

    notifyPropertyChanged(BR.loading);
    

    【讨论】:

      【解决方案2】:

      我想澄清一下,如果您使用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 );
      }
      

      【讨论】:

        【解决方案3】:

        在您的 XMl 文件结果解决方案顶部添加 &lt;import type="android.view.View" /&gt; 将如下所示

        <data>
            <import type="android.view.View" />
            <variable
                name="obj"
                type="com.you.modal.class" />
        </data>
        
        
         <import type="android.view.View" />
        

        【讨论】:

          猜你喜欢
          • 2017-11-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-09
          • 2016-09-18
          • 2018-03-23
          • 2013-05-02
          • 1970-01-01
          相关资源
          最近更新 更多