DataBinding 的Listview绑定
Databinding的常用操作:
之前在网上找了各种Databinding的教程,都比较杂乱,而且时间上也不同,都是几年前的帖子配置方法也有很大出入,下面是本人亲测使用的一些案例,用于分享,如有不对,还请指正:
1.使用:
现在的时间是: 2017-2-4 10:35:07
使用的工具版本分别是:
AndroidStudio 2.2.3
gradle 2.2.3
使用DataBinding直接在Module的.gradle中配置如下代码:
android { ... //一步搞定 dataBinding{ enabled = true; } }
2.简单绑定:
在使用之前需要说明的是布局文件(layout)跟以前的写法是不同的毕竟要绑定数据嘛:
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="cn.lxw.databinding.User"/> </data> <LinearLayout android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorAccent" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.firstName}" android:textSize="30sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.lastName}" android:textSize="30sp"/> </LinearLayout> </layout>
1.在原来的根布局外面要套一层 layout 并且在里面使用<data></data>来进行变量的声明:
这里我们声明了一个user变量,名叫"user",他的type指向的就是User这个Bean文件如下:
public class User { private String firstName; private String lastName; public User() { } @Override public String toString() { return "User{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + '}'; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } }
你可以使用get/set方法,也可以直接声明构造方法,静态变量~!
然后在Activity中使用:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding mainActivityBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); User user = new User("古", "树"); mainActivityBinding.setUser(user); }
这里 setContentView()
的老式方式进行了改变使用DataBindingUtil.setContentView()
他会返回一个特殊的类这个类的名字是根据你的布局文件名字来生成的,例如:
activity_main.xml 对应的就是 ActivityMainBinding; 去掉下划线,单词首字母大写,以"Binding"为后缀!
这样对应的控件上面就会显示对应的数据,这里就补贴图了.大家可以自己尝试!
3.ListView和Adapter:
3.1 布局文件:
很简单就是一个Listview,注意他的变量声明
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="adapter" type="android.widget.BaseAdapter"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" app:adapter="@{adapter}"/> </LinearLayout> </layout>
3.2 item的布局:
也很简单就是两个TextView,同样注意他们的变量声明
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="UserBean" type="cn.lxw.databinding.User"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:weightSum="1"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.3" android:text="@{UserBean.firstName}" android:textColor="#0094ff" android:textSize="26sp"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.7" android:text="@{UserBean.lastName??`数据为空`}" android:textColor="#00ff94" android:textSize="20sp"/> </LinearLayout> </layout>
3.3 Adapter的定义:
可以看到这里完全不需要使用ViewHolder了.
构造方法中的接受参数分别是:数据类型,listView的布局ID,以及,item中定义的对象Id.
public class MyAdapter<T> extends BaseAdapter { private List<T> data; private int itemLayoutId; private int variableId; public MyAdapter(List<T> data, int itemLayoutId, int variableId) { this.data = data; this.itemLayoutId = itemLayoutId; this.variableId = variableId; } @Override public int getCount() { return data.size(); } @Override public T getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewDataBinding binding; if (convertView == null) { binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), itemLayoutId, parent, false); } else { binding = DataBindingUtil.getBinding(convertView); } binding.setVariable(variableId, data.get(position)); return binding.getRoot(); } }
3.4 setAdapter
List<User> users = new ArrayList<>(); for (int i = 0; i < 100; i++) { User user; if (i % 2 == 0) { user = new User("L---" + i, null); } else { user = new User("L---" + i, "xw"); } users.add(user); } adapter = new MyAdapter<>(users, R.layout.item, BR.UserBean); secondBinding.setAdapter(adapter);
这里做个小彩蛋, 偶数的LastName直接设置为null,在item的布局中做了小处理,可以看上面,他的三元运算是有些区别的. 详细可以查看.
另外我是直接调用的secondBinding.setAdapter(adapter);
并没有调用secondBinding.lv.setAdapter(adapter)
因为在布局中声明了下面的变量:
<data> <variable name="adapter" type="android.widget.BaseAdapter"/> </data>
4.注意事项:
在layout中使用的三元运算符 有两种书写方式:
android:text="@{UserBean.lastName??`数据为空`}" android:text="@{UserBean.lastName==null ? `数据为空`: UserBean.lastName}"
,并且 如果涉及到字符串中还有字符串应当使用 ` 来区分
5.其特点:
由于春节期间玩的忘了型,现在想起来几个优点:
一个项目基本一个adapter就可以搞定列表了,只是item的布局不同而已传入构造方法就行.
在子线程中可以操作布局,大家可以自己试试,新开条线程,去修改view.
不用再去findviewbyid了, 直接使用 生成的类.viewid就行``
目前就是用过这么多,在群里问了些大神,对listview都没有过多的研究绑定数据.我也是各种google才弄得有些眉目, 如有不对还请指正.希望能帮到大家.