当前位置: 移动技术网 > IT编程>移动开发>Android > Android dataBinding与ListView及事件详解

Android dataBinding与ListView及事件详解

2019年07月24日  | 移动技术网IT编程  | 我要评论

白桦林居幼儿园,nba录像尼克斯,洛克王国3366

今天来了解一下android最新给我们带来的数据绑定框架——data binding library。数据绑定框架给我们带来了更大的方便性,以前我们可能需要在activity里写很多的findviewbyid,烦人的代码也增加了我们代码的耦合性,现在我们马上就可以抛弃那么多的findviewbyid。说到这里,有人可能会有个疑问:我使用一些注解框架也可以不用findviewbyid啊,是的,但是注解注定要拖慢我们代码的速度,data binding则不会,官网文档说还会提高解析xml的速度,最主要的data binding并不是单单减少了我们的findviewbyid,更多好处请往下看文章。

2015年google io大会分布了databinding库,能够更快捷便利的实现mvvm结构模式。但是,通过对databinding的学习,其中踩过得坑,今天要在这里记录一下。对于databinding一些比较基础的使用,在这里就不在记录了,毕竟现在google一下,出来很多的教程,而且,android developer官网中,也已经对其基本使用方法做了详细介绍,有英语基础的童鞋,还是去看比较官方的文章。

关于配置环境:

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

1 databinding{
2   enabled = true
3 }

但是,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的xml文件,代码如下:

<?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/list_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:adapter="@{adapter}"/>

  </linearlayout>
</layout>

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

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

<?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="userbean"
      type="com.lqy.newtestdemo.userbean"/>
  </data>

  <relativelayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

    <imageview
      android:id="@+id/image"
      android:layout_width="150dp"
      android:layout_height="100dp"
      android:layout_marginright="5dp"
      app:imageurl="@{userbean.picurl}"/>

    <linearlayout
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_torightof="@id/image"
      android:orientation="vertical">

      <textview
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{userbean.title}"
        android:textcolor="@android:color/black"
        android:textsize="20sp"/>

      <textview
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margintop="5dp"
        android:text="@{userbean.ctime}"/>

      <textview
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margintop="5dp"
        android:text="@{userbean.description}"/>
    </linearlayout>
  </relativelayout>
</layout>

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

package com.lqy.newtestdemo;

import android.content.context;
import android.databinding.databindingutil;
import android.databinding.viewdatabinding;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.baseadapter;

import java.util.list;

/**
 * 通用的adapter
 * created by lqy on 2016/10/10.
 */
public class listadapter<t> extends baseadapter {
  private context context;
  private list<t> list;
  private int layoutid;//单布局
  private int variableid;

  public listadapter(context context, list<t> list, int layoutid, int variableid) {
    this.context = context;
    this.list = list;
    this.layoutid = layoutid;
    this.variableid = variableid;
  }

  @override
  public int getcount() {
    return list.size();
  }

  @override
  public object getitem(int position) {
    return list.get(position);
  }

  @override
  public long getitemid(int position) {
    return position;
  }

  @override
  public view getview(int position, view convertview, viewgroup parent) {
    viewdatabinding binding = null;
    if (convertview == null){
      binding =databindingutil.inflate(layoutinflater.from(context),layoutid,parent,false);
    } else {
      binding = databindingutil.getbinding(convertview);
    }
    binding.setvariable(variableid,list.get(position));
    return binding.getroot();
  }
}

在这里可以看到,完全看不到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来关联上xml文件的listview的id值,然后才能调用其方法。用了databinding以后,只要用binding.listview就可以直接调用点击事件,完全不需要在findbyviewid,而listview其实就是xml里面的id值,而这个变形的id值其实是databinding根据id值自动生成的,你只需要记得你起的名字是什么,根据大概的规律来找到自己定义的id就好,这里并没有什么难度。不光listview可以这样用,这个同样适用于gridview。我在项目中也用到了gridview,亲测这个listadapter同样适用于gridview。并且,在我的项目里,是一个页面用到了两个gridview,只需要在data中定义两个不同的variable值,并且name的定义名称要定义不同的名字,这样就可以同时使用一个listadapter了,后期我会将源码放上来,这里只是记录一下我使用的方法,以及需要注意的地方。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网