我的Android成长之路(9)----黑科技dataBinding(二)
昨天我们一起学习了dataBinding的基础用法,我想你可能还停留在它只是不用再findViewById,其实不然,今天我们就来扩展延伸,看看这个框架到底有什么魔力让谷歌官方大力推崇。这里还没看昨天的基础运用的需要去看一看,附上链接:http://blog.csdn.net/cuper_/article/details/53197106
项目已经同步至github:https://github.com/nanchen2251/databinding
昨天我们解决了简单的使用以及在xml中进行属性的变换和一些简单的表达式放在xml文件中的使用问题,大家肯定有所疑问,我们在实际开发中肯定会用到很多的布局重用等,那么在这个框架中可否同样做到呢?另外,如果我们想用这个框架实现图片加载呢?大家都知道图片在xml中只能通过src设置本地图片,并没有提供通过url设置的属性,别急,楼主会把这个方法分享给你。
1)首先把昨天的xml代码放到一个独立的xml文件中,楼主这里叫user_layout.xml,这里设置图片通过使用app自定义属性设置图片url
![](/assets/blank.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 <layout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 xmlns:app="http://schemas.android.com/apk/res-auto"> 6 <data> 7 <variable 8 name="user" 9 type="com.example.nanchen.databindingdemo.User"> 10 </variable> 11 </data> 12 13 <LinearLayout 14 android:layout_width="0dp" 15 android:layout_weight = "1" 16 android:layout_height="match_parent" 17 android:gravity="center" 18 android:orientation="vertical" 19 tools:context="com.example.nanchen.databindingdemo.MainActivity"> 20 21 <ImageView 22 android:layout_width="100dp" 23 android:layout_height="100dp" 24 app:imageUrl="@{ user.icon }"/> 25 26 <TextView 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:textSize="25sp" 30 android:onClick="@{user.clickName}" 31 android:textColor="@{user.vip? 0xffff0000:0xff000000}" 32 android:text="@{user.nickName + `(` + user.name +`)`}"/> 33 34 <TextView 35 android:layout_width="wrap_content" 36 android:layout_height="wrap_content" 37 android:textSize="25sp" 38 android:onLongClick="@{user.longClickNickName}" 39 android:text="@{user.nickName ?? user.name}"/> 40 41 <TextView 42 android:layout_width="wrap_content" 43 android:layout_height="wrap_content" 44 android:textSize="25sp" 45 android:textColor="@{user.level < 3 ? 0xff03bbf9 : 0xfff60bdb }" 46 android:text="@{user.email}"/> 47 </LinearLayout> 48 </layout>
![](/assets/blank.gif)
2)然后修改主页面的xml文件,activity_main.xml,由于我们使用的是左右对称显示两个用户,所以我们应该用list,而不是之前的user,其中用到的尖括号用转义方法上一节已经讲过。
![](/assets/blank.gif)
<?xml version="1.0" encoding="utf-8"?> <layoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><data><!--<variable--><!--name="user"--><!--type="com.example.nanchen.databindingdemo.User">--><!--</variable>--><import type="com.example.nanchen.databindingdemo.User"/><variablename="users"type="java.util.List<User>"/></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="horizontal"tools:context="com.example.nanchen.databindingdemo.MainActivity"><includelayout="@layout/user_layout"app:user="@{ users[0] }"/><includelayout="@layout/user_layout"app:user="@{ users[1] }"/></LinearLayout> </layout>
![](/assets/blank.gif)
3)再改下Activity的代码
![](/assets/blank.gif)
package com.example.nanchen.databindingdemo;import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v7.app.AppCompatActivity;import com.example.nanchen.databindingdemo.databinding.ActivityMainBinding;import java.util.ArrayList; import java.util.List;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);User user = new User();user.setName("刘世麟");user.setNickName("南尘");user.setEmail("liushilin@qq.com");user.setVip(true);user.setLevel(5);user.setIcon("http://qlogo1.store.qq.com/qzone/503233512/503233512/100?1311741184"); // binding.setUser(user); User user1 = new User();user1.setName("春春儿");user1.setNickName(null);user1.setVip(false);user1.setEmail("nanchen@qq.com");user1.setLevel(1); // binding.setUser(user1); List<User> list = new ArrayList<>();list.add(user);list.add(user1);binding.setUsers(list); // binding.setUser(new User("刘世麟","南尘","liushilin@qq.com")); } }
![](/assets/blank.gif)
看看运行效果
看到这里,也许小伙伴会说,切,不就一个include吗,这个框架还是没带来飞一般的感觉,别急,还有更厉害的使用ListView之类的等着你
我们来看看listView如何实现。
1)自然需要先定义一个list_item.xml,用于基本Item的布局。
![](/assets/blank.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <layout 4 xmlns:android="http://schemas.android.com/apk/res/android" 5 xmlns:app="http://schemas.android.com/apk/res-auto"> 6 7 <data> 8 <variable 9 name="user" 10 type="com.example.nanchen.databindingdemo.User"/> 11 </data> 12 13 <LinearLayout 14 android:layout_width="match_parent" 15 android:layout_height="match_parent" 16 android:orientation="horizontal" 17 android:onClick="@{ user.click }"> 18 19 <ImageView 20 android:layout_width="100dp" 21 android:layout_height="100dp" 22 app:imageUrl="@{user.icon}"/> 23 24 <TextView 25 android:layout_width="match_parent" 26 android:layout_height="match_parent" 27 android:text="@{user.name}" 28 android:gravity="center"/> 29 30 </LinearLayout> 31 </layout>
![](/assets/blank.gif)
2)写一个通用的适配器Adaper,注意这里和你以往写的ListView的适配器完全不一样,我们多了两个属性,一个是layoutId,一个是属性id
![](/assets/blank.gif)
1 package com.example.nanchen.databindingdemo; 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 * ListView的通用Adapter 15 * Created by 南尘 on 16-7-18. 16 */ 17 public class CommonAdapter<T> extends BaseAdapter { 18 private Context context;//上下文环境 19 private List<T> list;//通用的,不知道数据 20 private int layoutId;//通用的,不知道布局 21 private int variableId;//变量的id 22 23 /** 24 * 构造方法 25 */ 26 public CommonAdapter(Context context, List<T> list, int layoutId, int variableId) { 27 this.context = context; 28 this.list = list; 29 this.layoutId = layoutId; 30 this.variableId = variableId; 31 } 32 33 @Override 34 public int getCount() { 35 if (list!=null) 36 return list.size(); 37 return 0; 38 } 39 40 @Override 41 public Object getItem(int position) { 42 return list.get(position); 43 } 44 45 @Override 46 public long getItemId(int position) { 47 return position; 48 } 49 50 @Override 51 public View getView(int position, View convertView, ViewGroup parent) { 52 ViewDataBinding binding = null; 53 if (convertView == null){ 54 binding = DataBindingUtil.inflate(LayoutInflater.from(context),layoutId,parent,false); 55 }else{ 56 binding = DataBindingUtil.getBinding(convertView); 57 } 58 binding.setVariable(variableId,list.get(position)); 59 return binding.getRoot(); 60 } 61 }
![](/assets/blank.gif)
3)在xml中布局,这个比较简单,先在配置文件中把这个更改为程序入口,并且添加网络操作权限,这里用了BR文件,BR文件和R文件都是系统会自动生成的,只是R文件用于资源的id。图片我们就使用一个默认的
![](/assets/blank.gif)
1 package com.example.nanchen.databindingdemo; 2 3 import android.databinding.DataBindingUtil; 4 import android.os.Bundle; 5 import android.support.v7.app.AppCompatActivity; 6 7 import com.example.nanchen.databindingdemo.databinding.ActivityDataBindingListBinding; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 public class DataBindingListActivity extends AppCompatActivity { 13 14 @Override 15 protected void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 // setContentView(R.layout.activity_data_binding_list); 18 ActivityDataBindingListBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_data_binding_list); 19 20 List<User> list = new ArrayList<>(); 21 for (int i = 0; i < 100; i++) { 22 User user = new User(); 23 user.setName("用户 " + i ); 24 user.setIcon("http://qlogo1.store.qq.com/qzone/503233512/503233512/100?1311741184"); 25 list.add(user); 26 } 27 CommonAdapter<User> adapter = new CommonAdapter<>( 28 this, list, R.layout.list_item, com.example.nanchen.databindingdemo.BR.user); 29 binding.setAdapter(adapter); 30 31 } 32 33 34 }
![](/assets/blank.gif)
4)大概可以运行了哈。
5)如何添加点击事件呢?别慌,在我们的User中加入点击方法就好了。
![](/assets/blank.gif)
1 package com.example.nanchen.databindingdemo; 2 3 import android.view.View; 4 import android.widget.Toast; 5 6 /** 7 * 继承,观察可刷新 8 * Created by 南尘 on 16-7-18. 9 */ 10 public class User { 11 private String name;//用户名 12 private String nickName;//昵称 13 private String email;//邮箱 14 15 private boolean vip;//是否是会员 16 private int level;//级别 17 private String icon; 18 19 public String getIcon() { 20 return icon; 21 } 22 23 public void setIcon(String icon) { 24 this.icon = icon; 25 } 26 27 public int getLevel() { 28 return level; 29 } 30 31 public void setLevel(int level) { 32 this.level = level; 33 } 34 35 public boolean isVip() { 36 return vip; 37 } 38 39 public void setVip(boolean vip) { 40 this.vip = vip; 41 } 42 43 public User() { 44 } 45 46 public User(String name, String nickName, String email) { 47 this.name = name; 48 this.nickName = nickName; 49 this.email = email; 50 } 51 52 public String getEmail() { 53 return email; 54 } 55 56 public void setEmail(String email) { 57 this.email = email; 58 } 59 60 public String getName() { 61 return name; 62 63 } 64 65 public void setName(String name) { 66 this.name = name; 67 } 68 69 public String getNickName() { 70 return nickName; 71 } 72 73 public void setNickName(String nickName) { 74 this.nickName = nickName; 75 } 76 77 public void clickName(View view){ 78 Toast.makeText(view.getContext(),"点击了用户名:" + name,Toast.LENGTH_SHORT).show(); 79 } 80 81 public boolean longClickNickName(View view){ 82 Toast.makeText(view.getContext(),"长按了昵称:"+nickName,Toast.LENGTH_SHORT).show(); 83 return true; 84 } 85 86 public void click(View view){ 87 setName(getName() + "( 已点击 )"); 88 } 89 }
![](/assets/blank.gif)
6)这里我们点击了用户2,什么情况?没刷新!!!!!,哦,哪里出了问题!
7)调皮的滑动了一下滚动条,再回去发现才刷新更改了。
9)e duo key,这里也太out了吧,说好的最屌框架呢?说好的要愉快一辈子呢?
仔细一看,才发现我们的逻辑中出了一点小问题,这样的话虽然你的list中的数据改变了,但是list并不知道,而这个adapter又没有刷新数据的方法,怎么办?
这里用到一个观察者模式,只需要把User继承BaseObservable类,并且在要更改的属性上加一个@Bindble,再在setName方法中加入这样一句话则可。
//刷新变量(变量id) notifyPropertyChanged(com.example.nanchen.databindingdemo.BR.name);
![](/assets/blank.gif)
1 package com.example.nanchen.databindingdemo; 2 3 import android.databinding.BaseObservable; 4 import android.databinding.Bindable; 5 import android.view.View; 6 import android.widget.Toast; 7 8 /** 9 * 继承,观察可刷新 10 * Created by 南尘 on 16-7-18. 11 */ 12 public class User extends BaseObservable { 13 private String name;//用户名 14 private String nickName;//昵称 15 private String email;//邮箱 16 17 private boolean vip;//是否是会员 18 private int level;//级别 19 private String icon; 20 21 public String getIcon() { 22 return icon; 23 } 24 25 public void setIcon(String icon) { 26 this.icon = icon; 27 } 28 29 public int getLevel() { 30 return level; 31 } 32 33 public void setLevel(int level) { 34 this.level = level; 35 } 36 37 public boolean isVip() { 38 return vip; 39 } 40 41 public void setVip(boolean vip) { 42 this.vip = vip; 43 } 44 45 public User() { 46 } 47 48 public User(String name, String nickName, String email) { 49 this.name = name; 50 this.nickName = nickName; 51 this.email = email; 52 } 53 54 public String getEmail() { 55 return email; 56 } 57 58 public void setEmail(String email) { 59 this.email = email; 60 } 61 62 @Bindable 63 public String getName() { 64 return name; 65 66 } 67 68 public void setName(String name) { 69 this.name = name; 70 //刷新变量(变量id) 71 notifyPropertyChanged(com.example.nanchen.databindingdemo.BR.name); 72 } 73 74 public String getNickName() { 75 return nickName; 76 } 77 78 public void setNickName(String nickName) { 79 this.nickName = nickName; 80 } 81 82 public void clickName(View view){ 83 Toast.makeText(view.getContext(),"点击了用户名:" + name,Toast.LENGTH_SHORT).show(); 84 } 85 86 public boolean longClickNickName(View view){ 87 Toast.makeText(view.getContext(),"长按了昵称:"+nickName,Toast.LENGTH_SHORT).show(); 88 return true; 89 } 90 91 public void click(View view){ 92 setName(getName() + "( 已点击 )"); 93 } 94 }
![](/assets/blank.gif)
10)再次运行:
现在好多了嘛,一点击就刷新了,是不是很吊?额,现在是点击整个item都可以刷新属性界面,好吧,其实无论你点击哪里,只要你加上这个click方法作为自定义属性,都可以实现这个功能,这里你要在原来的思路上实现是不是相当麻烦,而这个框架让你只需要移动一行代码的位置就可以,很高端大气上档次有木有?
这里做个示范,假如你是点击头像更改,只需要这样。
![](/assets/blank.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <layout 4 xmlns:android="http://schemas.android.com/apk/res/android" 5 xmlns:app="http://schemas.android.com/apk/res-auto"> 6 7 <data> 8 <variable 9 name="user" 10 type="com.example.nanchen.databindingdemo.User"/> 11 </data> 12 13 <LinearLayout 14 android:layout_width="match_parent" 15 android:layout_height="match_parent" 16 android:orientation="horizontal" 17 > 18 19 <ImageView 20 android:layout_width="100dp" 21 android:layout_height="100dp" 22 app:imageUrl="@{user.icon}" 23 android:onClick="@{ user.click }"/> 24 25 <TextView 26 android:layout_width="match_parent" 27 android:layout_height="match_parent" 28 android:text="@{user.name}" 29 android:gravity="center"/> 30 31 </LinearLayout> 32 </layout>
![](/assets/blank.gif)
不仅可以放在这里,你还可以放在任何地方,无论是在ListView里面还是外面。
肯定这个框架还有其他的东西的,大家一起发掘咯~
转自南尘随笔
我的Android成长之路(9)----黑科技dataBinding(二)相关推荐
- 电系魔法师成长之路—仪器仪表学习(二)设计T型和Π型衰减器
电系魔法师成长之路-仪器仪表学习(二)设计T型和Π型衰减器 一.用途 衰减器是一种提供衰减的电子元器件, 广泛地应用于电子设备中,它的主要用途是:(1)调整电路中信号的大小:(2)在比较法测量电路 ...
- Python人脸识别黑科技(二):教你使用python+Opencv完成人脸解锁
继上一篇"Python人脸识别黑科技(一):50行代码运用Python+OpenCV实现人脸追踪+详细教程+快速入门+图像识",那么今天我们来讲关于使用python+opencv+ ...
- 一个大神的Android成长之路
这篇文章是我的一个朋友写的,总结了这些年的技术成长之路,我觉得对于很多技术人都有借鉴的作用,技术是相通的,不要整天想一口气吃成一个胖子,不积跬步无以至千里,既然选择了技术这条路,就不畏艰辛,苦中有甜, ...
- 王小二C:一个大神的Android成长之路
这篇文章是我的一个朋友写的,总结了这些年的技术成长之路,我觉得对于很多技术人都有借鉴的作用,技术是相通的,不要整天想一口气吃成一个胖子,不积跬步无以至千里,既然选择了技术这条路,就不畏艰辛,苦中有甜, ...
- android beam苹果,安卓多年黑科技 苹果终于蹒跚追上_苹果 iPhone X _手机评测-中关村在线...
安卓多年黑科技 苹果终于蹒跚追上 用"Android系统多年的黑科技,iOS现在终于用上了"这一句话来形容iOS 11.3支持刷公交卡这个行为一点也不为过.是的,早在三四年前多数A ...
- 苹果充电线android头断了,【黑科技数据线!断了都能用!】 苹果安卓数据线 快速修复永不断线...
原标题:[黑科技数据线!断了都能用!] 苹果安卓数据线 快速修复永不断线 这个世界上最爽的事情是什么呢? 是躺在床上玩手机 那么最痛苦的事情是什么呢 玩到手机没电的时候数据线坏了! 这说到数据线有什么 ...
- 快速启动android模拟器,逍遥安卓模拟器黑科技发布电脑玩手游永久快速启动
原标题:逍遥安卓模拟器黑科技发布电脑玩手游永久快速启动 所有使用安卓模拟器的用户,在电脑上玩手游的过程中,等待安卓模拟器以及游戏的启动是最煎熬的过程,尤其是当安卓模拟器使用过一段时间之后,启动的速度会 ...
- Android成长之路-实现简单动画
实现简单动画: 在drawable目录中放入图片, 并且创建xml文件 frame.xml 存入图片,如下: [java] view plaincopy <pre class="htm ...
- Android九点阵手势识别,能量黑科技模块八-九:两路按键颜色手势魔块
8. 两路按键魔块 模块一共有两路硅胶按键,可以检测按键是否按下.当按键按下时,对应按键背后的红色LED会亮,并且返回触发信号,按键按下事件为真.另外按键键帽上可安装乐高十字插销. 8.1. 详细介绍 ...
最新文章
- 函数在机器底层是如何实现的_智能货柜专题三:如何实现不同机器“千机千面”?...
- java计算5 5_Java基础学习笔记 -- 5(运算符)
- mysql in sql注入_在 SQL 注入攻击中检查数据库
- XSS 前端防火墙 —— 天衣无缝的防护
- js json转xml(可自定义属性,区分大小写)
- python sys模块_Python 基础(二十):sys 模块
- linux -对称加密、 非对称加密
- 微信公众号模板消息 access_token missing
- 谈谈坚持写博客的感悟
- 复印机扫描仪错误怎么回事_打印机扫描后出现错误怎么处理?
- 培养使用计算机的良好道德规范,浅谈如何提高学生学习信息技术的兴趣
- 三星证实遭黑客入侵:Galaxy手机源代码泄露
- android 播放提示音,[转载]android播放音效例子 (翻页音效、警报音效通用
- 利用samba漏洞入侵linux主机(samba低版本漏洞利用)
- 安卓图片处理Picasso的解析使用
- Thinkpad笔记本刷BIOS教程
- 基于横向轨迹误差法(Cross-track Error)P 导航二维控制 实现无人机水平面导航控制
- MAC10.15.4无法开启ToDesk屏幕录制权限
- autofac 作用域_C#编程之.Net Core 学习之路-AutoFac的使用
- ThreeJS入门篇(1)开场扯淡
热门文章
- 对接twitter第三方登录踩的坑
- 分享下.NET程序读取二代身份证(附源码
- 十大编程软件排行榜——pow_na的博客
- 荣耀是不是没有鸿蒙了,不只是华为手机!荣耀或将接入鸿蒙,选定这款机型大有讲究...
- 数据猿专栏专家张涵诚:从技术到生态构建,云计算棋局越来越大,该如何成功落地?...
- 高德地图关于多类图标点切换问题
- 新手主播首播带货超20万,直播的标准脚本免费传授
- java的rsa加密_Java实现RSA加密算法
- codeforces 855C 树DP
- 工作效率软件:番茄土豆 http://pomotodo.com/