你的位置:首页 > 操作系统

[操作系统]dataBinding与ListView及事件


2015年Google IO大会分布了DataBinding库,能够更快捷便利的实现MVVM结构模式。但是,通过对DataBinding的学习,其中踩过得坑,今天要在这里记录一下。对于DataBinding一些比较基础的使用,在这里就不在记录了,毕竟现在Google一下,出来很多的教程,而且,android developer官网中,也已经对其基本使用方法做了详细介绍,有英语基础的童鞋,还是去看比较官方的文章。如果英文基础不太好的,https://realm.io/cn/news/data-binding-android-boyar-mount/推荐这个博客,会有很大收获的,同时,谢谢棉花糖的这篇文章,解决了很多的疑惑。

关于配置环境:

2.0以上的 Android Studio 已经内置了对 Android Data Binding 框架的支持,配置起来也很简单,只需要在 app 的 build.gradle 文件中添加下面的内容就好了

1 dataBinding{2   enabled = true3 }

但是,gradle的版本,至少得是1.5.0以上,否则配置会很麻烦。因为本人使用的Android studio版本是2.1.3,gradle也更改成了2.1.3,所以,不需要做过多的设置。但是有一点,Android studio对DataBinding的支持还不是完全的兼容,有些地方确实有点坑。

关于使用:

最近,把之前写的一个小项目,更改成了DataBinding的架构模式。感觉Android studio2.1.3版本已经很新了,但是对于一些属性的提示还不是很好,并不是完全支持的。比较基础的使用方法,在这里就不在提了,主要是写一下对ListView以及GridView的使用,还有就是对adapter的写法,以及点击跳转的事件。

首先,先是写一个ListView或者GridView的

 1 <??> 2 <layout 3   ="http://schemas.android.com/apk/res/android" 4   ="http://schemas.android.com/apk/res-auto"> 5  6   <data> 7  8     <variable 9       name="adapter"10       type="android.widget.BaseAdapter"/>11 12   </data>13 14   <LinearLayout15     android:layout_width="match_parent"16     android:layout_height="match_parent"17     android:orientation="vertical">18 19     <ListView20       android:id="@+id/list_view"21       android:layout_width="match_parent"22       android:layout_height="match_parent"23       app:adapter="@{adapter}"/>24 25   </LinearLayout>26 </layout>

View Code

重点在app:adapter="@{adapter}"这句话中,主要是自定义一个adapter,来对ListView或者GridView进行数据的绑定。

然后,最主要的,其实就是适配器的写法。在以往的写法中,BaseAdapter肯定需要ViewHolder来进行视图的绑定,并且做缓存。那么,在DataBinding中,完全不需要ViewHolder,而且,针对单布局的话,完全可以写个通用的adapter,针对一般的小项目,这个adapter完全的够用,那么,现在先来随便写一个adapter的item的

 1 <??> 2 <layout ="http://schemas.android.com/apk/res/android" 3     ="http://schemas.android.com/apk/res-auto"> 4  5   <data> 6     <variable 7       name="userbean" 8       type="com.lqy.newtestdemo.UserBean"/> 9   </data>10 11   <RelativeLayout12     android:layout_width="match_parent"13     android:layout_height="match_parent"14     android:padding="10dp">15 16     <ImageView17       android:id="@+id/image"18       android:layout_width="150dp"19       android:layout_height="100dp"20       android:layout_marginRight="5dp"21       app:imageUrl="@{userbean.picUrl}"/>22 23     <LinearLayout24       android:layout_width="wrap_content"25       android:layout_height="wrap_content"26       android:layout_toRightOf="@id/image"27       android:orientation="vertical">28 29       <TextView30         android:layout_width="wrap_content"31         android:layout_height="wrap_content"32         android:text="@{userbean.title}"33         android:textColor="@android:color/black"34         android:textSize="20sp"/>35 36       <TextView37         android:layout_width="wrap_content"38         android:layout_height="wrap_content"39         android:layout_marginTop="5dp"40         android:text="@{userbean.ctime}"/>41 42       <TextView43         android:layout_width="wrap_content"44         android:layout_height="wrap_content"45         android:layout_marginTop="5dp"46         android:text="@{userbean.description}"/>47     </LinearLayout>48   </RelativeLayout>49 </layout>

View Code

可以看到,布局中,主要是通过data中的variable属性来标识一个变量名,在控件中,只需要android:text="@{userbean.title}",就能进行变量的赋值,这个在基础用法中都有说明,这里就不在论述。下面就是重点了,关于BaseAdapter的写法,废话不多说,直接上代码:

 1 package com.lqy.newtestdemo; 2  3 import android.content.Context; 4 import android.databinding.DataBindingUtil; 5 import android.databinding.ViewDataBinding; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.ViewGroup; 9 import android.widget.BaseAdapter;10 11 import java.util.List;12 13 /**14  * 通用的adapter15  * Created by LQY on 2016/10/10.16 */17 public class ListAdapter<T> extends BaseAdapter {18   private Context context;19   private List<T> list;20   private int layoutId;//单布局21   private int variableId;22 23   public ListAdapter(Context context, List<T> list, int layoutId, int variableId) {24     this.context = context;25     this.list = list;26     this.layoutId = layoutId;27     this.variableId = variableId;28   }29 30   @Override31   public int getCount() {32     return list.size();33   }34 35   @Override36   public Object getItem(int position) {37     return list.get(position);38   }39 40   @Override41   public long getItemId(int position) {42     return position;43   }44 45   @Override46   public View getView(int position, View convertView, ViewGroup parent) {47     ViewDataBinding binding = null;48     if (convertView == null){49       binding =DataBindingUtil.inflate(LayoutInflater.from(context),layoutId,parent,false);50     } else {51       binding = DataBindingUtil.getBinding(convertView);52     }53     binding.setVariable(variableId,list.get(position));54     return binding.getRoot();55   }56 }

View Code

在这里可以看到,完全看不到ViewHolder的踪迹,而且,只需几行的代码,就能将适配器写好,并且,可以用到多个ListView或者GridView中,adapter设置好以后,只需要在Activity中加入这样两句话就可以:

1 ListAdapter<UserBean> adapter = new ListAdapter<>(MainActivity.this, list, R.layout.item, BR.userbean);2 binding.setAdapter(adapter);

binding怎么来的,这里就不在论述,请大家去看基础使用方法。那么,在写一个通用的adapter的时候,我们可以看到ListAdapter的泛型所代表的,其实就是一个Bean文件,是你需要赋值的那个文件。list代表的是一个List的列表值,这个列表可以是你在Json解析出来得列表值,也可以是你通过list.add所附的值,这些就要看你项目的需要了。最坑的地方在BR上,BR说起来就跟项目本身会产生的R文件是一个道理,只不过,BR是DataBinding所产生的一个R文件,也需要导入一个BR的包,当然,如果项目没什么问题的,Android studio会提醒这个BR值导包的。我踩到的坑是,明明代码中没有任何问题,也没有错出现,第一次运行成功了,第二次在运行的时候,就提示BR文件找不到,包删了重新导都导不进去,clean一下不管用,包还是导不进去,Rebuild一下,提示找不到BR包,怎么都过不去。最后我只能把整个Android studio关掉在重新打开,发现BR包导进去了,然后也没BUG了,运行也成功了。。。所以,如果你也遇到这种情况了,就请关闭Android studio并且重新打开一下,如果还没好,就证明你的程序其实是有错误的,仔细找找就好。差不多就这个样子吧。

下面还有一个问题,那就是关于点击跳转的问题。在其他的一些教程里面,可能只写到了onClick事件的绑定,其中能实现的,就是改变当前数值或者字段。但是,还没一些教程来讲如何进行跳转。现在我就来讲一下跳转如何实现,先看代码:

binding.listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {      @Override      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {        Intent intent = new Intent(MainActivity.this, WebActivity.class);        intent.putExtra("url", list.get(position).getUrl());        startActivity(intent);      }    });

在Activity页面,还可以使用setOnItemClickListener方法。之前在调用setOnItemClickListener方法的时候,先是定义一个ListView的变量名,然后findByViewId来关联上

有写的不对的地方希望大伙指出来,也希望我这篇文章能帮到正在DataBinding中挣扎的童鞋。