DataBinding的基本使用(五)

2023-05-16

DataBinding的基本使用(五)

DataBinding基本使用包括以下内容:
- 单纯的摆脱findviewbyid
- 绑定基本数据类型及String
- 绑定Model数据
- 绑定事件
- 通过静态方法转换数据类型
- 通过运算符操作数据
- 自定义Binding的类名
- 绑定相同Model的操作
- model变量改变自动更新数据
- 绑定List/Map等集合数据
- Observable自动更新
- Databinding与include标签的结合
- DataBinding与RecyclerView的结合

3.12 Databinding与include标签的结合

布局文件

activity_five.xml

<?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局-->
<layout>

    <data >
        <import type="www.zhang.com.databinding.model.Content"/>
        <variable
            name="con"
            type="Content"/>
    </data>
    <!--我们需要展示的布局-->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar"
            android:layout_height="56dp"
            android:layout_width="match_parent"
            bind:content="@{con}" />
 <!--通过命名空间将写有toolbar的xml文件中定义的content对象作为属性绑定con对象,这2个对象是同一个类-->
            <TextView
                android:text="@string/app_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    </LinearLayout>
</layout>

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<layout >
    <data>
        <import type="www.zhang.com.databinding.model.Content"/>
      <variable
          name="content"
          type="Content"/>
    </data>

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="56dp"
    android:layout_width="match_parent"
    app:title="@{content.title}"
    app:subtitle="@{content.subTitle}"
    android:background="@color/colorPrimary"
    app:titleTextColor="@android:color/white"
    app:subtitleTextColor="@android:color/white" />
</layout>

在activity_five.xml中的include属性中定义了一个id,同时又在toolbar.xml中的Toolbar标签中又定义了一个id,其作用是通过binding.toolbar.toolbar等同于Toolbar控件,可以方便做一些操作等

FiveActivity中

public class FiveActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

        ActivityFiveBinding binding =DataBindingUtil.setContentView(FiveActivity.this, R.layout.activity_five);

        Content con = new Content("Title","SubTitle");
        binding.setCon(con);

//        binding.toolbar.setContent(con);  //这个测试没有效果,不会显示toolbar的title/subTitle
//        binding.toolbar.toolbar.setTitle(""); 
//        binding.toolbar.toolbar.setSubtitle("");

        //下面的代码也可以通过DataBinding绑定数据
        binding.toolbar.toolbar.setNavigationIcon(R.mipmap.ic_launcher);
        setSupportActionBar(binding.toolbar.toolbar);
        binding.toolbar.toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

Content

public class Content extends BaseObservable {
    private String title;
    private String subTitle;

    public Content(String title, String subTitle) {
        this.title = title;
        this.subTitle = subTitle;
    }

    @Bindable public String getSubTitle() {
        return subTitle;
    }

    public void setSubTitle(String subTitle) {
        this.subTitle = subTitle;
        notifyPropertyChanged(BR.subTitle);
    }

    @Bindable public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
        notifyPropertyChanged(BR.title);
    }
}
3.13 DataBinding与RecyclerView的结合

布局文件

activity_five.xml

<?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局-->
<layout>

    <data >
        <import type="www.zhang.com.databinding.model.Content"/>
        <variable
            name="con"
            type="Content"/>
    </data>
    <!--我们需要展示的布局-->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar"
            android:layout_height="56dp"
            android:layout_width="match_parent"
            bind:content="@{con}" />
        <!--通过命名空间将写有toolbar的xml文件中定义的content对象作为属性绑定con对象,这2个对象是同一个类-->
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    </LinearLayout>
</layout>

recycler_item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <variable
            name="str"
            type="String"/>
    </data>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:orientation="vertical">

        <TextView
            android:text="@{str}"
            android:gravity="center_vertical"
            android:textColor="@android:color/black"
            android:textSize="16sp"
            android:layout_width="match_parent"
            android:layout_height="48dp" />
    </LinearLayout>
</layout>

FiveActivity

public class FiveActivity extends AppCompatActivity {

    private ActivityFiveBinding binding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

        binding = DataBindingUtil.setContentView(FiveActivity.this, R.layout.activity_five);

        initToolbar();
        initRecyclerView();
    }

    private void initRecyclerView() {
        LinearLayoutManager manager = new LinearLayoutManager(FiveActivity.this);
        binding.recycler.setLayoutManager(manager);
        binding.recycler.setHasFixedSize(true);
        MyAdapter adapter = new MyAdapter(getApplicationContext());
        binding.recycler.setAdapter(adapter);
    }

    private void initToolbar() {
        Content con = new Content("Title","SubTitle");
        binding.setCon(con);

//        binding.toolbar.setContent(con);  //这个测试没有效果,不会显示toolbar的title/subTitle
//        binding.toolbar.toolbar.setTitle("");
//        binding.toolbar.toolbar.setSubtitle("");

        //下面的代码也可以通过DataBinding绑定数据
        binding.toolbar.toolbar.setNavigationIcon(R.mipmap.ic_launcher);
        setSupportActionBar(binding.toolbar.toolbar);
        binding.toolbar.toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

MyAdapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private Context mContext;
    String[] datas;

    public MyAdapter(Context context) {
        mContext = context;
        datas = context.getResources().getStringArray(R.array.item_list);
    }

    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(mContext), R.layout.recycler_item, parent, false);
        return new MyViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {
        String name = datas[position];
        holder.getBinding().setVariable(www.zhang.com.databinding.BR.str,name);
        //holder.getBinding().setStr(name); //两者都可以

        //executePendingBindings()方法说明
        // When a variable or observable changes, the binding will be scheduled to change before the next frame. 
        // There are times, however, when binding must be executed immediately. 
        // To force execution, use the executePendingBindings() method.
        holder.getBinding().executePendingBindings();//此方法必须执行在UI线程,当绑定的数据修改时更新视图(不知道翻译的准不准)
    }

    @Override
    public int getItemCount() {
        return datas.length;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private RecyclerItemBinding binding;

        public MyViewHolder(ViewDataBinding binding) {
            super(binding.getRoot());
            this.binding = (RecyclerItemBinding) binding;
        }

        public RecyclerItemBinding getBinding() {
            return binding;
        }

        public void setBinding(RecyclerItemBinding binding) {
            this.binding = binding;
        }
    }
}

参考文章

Google官方文档

Android数据绑定框架DataBinding

Android-MVVM架构-Data Binding的使用

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DataBinding的基本使用(五) 的相关文章

随机推荐