android 黑技术,android黑科技

昨天我们一起学习了dataBinding的基础用法,我想你可能还停留在它只是不用再findViewById,其实不然,今天我们就来扩展延伸,看看这个框架到底有什么魔力让谷歌官方大力推崇。这里还没看昨天的基础运用的需要去看一看,附上链接:http://www.cnblogs.com/liushilin/p/5681473.html

另外,由于楼主github出了点小问题,暂时无法把demo同步到git网上,所以需要源码的小伙伴请留言邮箱,楼主一定会尽快邮件给你。能帮忙解决git无法同步的问题的也麻烦帮帮楼主吧。

昨天我们解决了简单的使用以及在xml中进行属性的变换和一些简单的表达式放在xml文件中的使用问题,大家肯定有所疑问,我们在实际开发中肯定会用到很多的布局重用等,那么在这个框架中可否同样做到呢?另外,如果我们想用这个框架实现图片加载呢?大家都知道图片在xml中只能通过src设置本地图片,并没有提供通过url设置的属性,别急,楼主会把这个方法分享给你。

1)首先把昨天的xml代码放到一个独立的xml文件中,楼主这里叫user_layout.xml,这里设置图片通过使用app自定义属性设置图片url

76180208_1.gif

1 <?xml version="1.0" encoding="utf-8"?>

2

4 xmlns:tools="http://schemas.android.com/tools"

5 xmlns:app="http://schemas.android.com/apk/res-auto">

6

7

9 type="com.example.nanchen.databindingdemo.User">

10

11

12

13

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

23 android:layout_height="100dp"

24 app:imageUrl="@{ user.icon }"/>

25

26

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

36 android:layout_height="wrap_content"

37 android:textSize="25sp"

38 android:onLongClick="@{user.longClickNickName}"

39 android:text="@{user.nickName ?? user.name}"/>

40

41

43 android:layout_height="wrap_content"

44 android:textSize="25sp"

45 android:textColor="@{user.level < 3 ? 0xff03bbf9 : 0xfff60bdb }"

46 android:text="@{user.email}"/>

47

48

76180208_1.gif

2)然后修改主页面的xml文件,activity_main.xml,由于我们使用的是左右对称显示两个用户,所以我们应该用list,而不是之前的user,其中用到的尖括号用转义方法上一节已经讲过。

76180208_1.gif

xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools">

name="users"type="java.util.List<User>"/>

android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="horizontal"tools:context="com.example.nanchen.databindingdemo.MainActivity">

layout="@layout/user_layout"app:user="@{ users[0] }"/>

layout="@layout/user_layout"app:user="@{ users[1] }"/>

76180208_1.gif

3)再改下Activity的代码

76180208_1.gif

packagecom.example.nanchen.databindingdemo;importandroid.databinding.DataBindingUtil;importandroid.os.Bundle;importandroid.support.v7.app.AppCompatActivity;importcom.example.nanchen.databindingdemo.databinding.ActivityMainBinding;importjava.util.ArrayList;importjava.util.List;public class MainActivity extendsAppCompatActivity {

@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//setContentView(R.layout.activity_main);

ActivityMainBinding binding= DataBindingUtil.setContentView(this,R.layout.activity_main);

User user= newUser();

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= newUser();

user1.setName("春春儿");

user1.setNickName(null);

user1.setVip(false);

user1.setEmail("nanchen@qq.com");

user1.setLevel(1);//binding.setUser(user1);

List list = new ArrayList<>();

list.add(user);

list.add(user1);

binding.setUsers(list);//binding.setUser(new User("刘世麟","南尘","liushilin@qq.com"));

}

}

76180208_1.gif

看看运行效果

76180208_2.png

看到这里,也许小伙伴会说,切,不就一个include吗,这个框架还是没带来飞一般的感觉,别急,还有更厉害的使用ListView之类的等着你

我们来看看listView如何实现。

1)自然需要先定义一个list_item.xml,用于基本Item的布局。

76180208_1.gif

1 <?xml version="1.0" encoding="utf-8"?>

2

3

5 xmlns:app="http://schemas.android.com/apk/res-auto">

6

7

8

10 type="com.example.nanchen.databindingdemo.User"/>

11

12

13

15 android:layout_height="match_parent"

16 android:orientation="horizontal"

17 android:onClick="@{ user.click }">

18

19

21 android:layout_height="100dp"

22 app:imageUrl="@{user.icon}"/>

23

24

26 android:layout_height="match_parent"

27 android:text="@{user.name}"

28 android:gravity="center"/>

29

30

31

76180208_1.gif

2)写一个通用的适配器Adaper,注意这里和你以往写的ListView的适配器完全不一样,我们多了两个属性,一个是layoutId,一个是属性id

76180208_1.gif

1 packagecom.example.nanchen.databindingdemo;2

3 importandroid.content.Context;4 importandroid.databinding.DataBindingUtil;5 importandroid.databinding.ViewDataBinding;6 importandroid.view.LayoutInflater;7 importandroid.view.View;8 importandroid.view.ViewGroup;9 importandroid.widget.BaseAdapter;10

11 importjava.util.List;12

13 /**

14 * ListView的通用Adapter15 * Created by 南尘 on 16-7-18.16 */

17 public class CommonAdapter extendsBaseAdapter {18 private Context context;//上下文环境

19 private List list;//通用的,不知道数据

20 private int layoutId;//通用的,不知道布局

21 private int variableId;//变量的id

22

23 /**

24 * 构造方法25 */

26 public CommonAdapter(Context context, List list, int layoutId, intvariableId) {27 this.context =context;28 this.list =list;29 this.layoutId =layoutId;30 this.variableId =variableId;31 }32

33 @Override34 public intgetCount() {35 if (list!=null)36 returnlist.size();37 return 0;38 }39

40 @Override41 public Object getItem(intposition) {42 returnlist.get(position);43 }44

45 @Override46 public long getItemId(intposition) {47 returnposition;48 }49

50 @Override51 public View getView(intposition, 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 returnbinding.getRoot();60 }61 }

76180208_1.gif

3)在xml中布局,这个比较简单,先在配置文件中把这个更改为程序入口,并且添加网络操作权限,这里用了BR文件,BR文件和R文件都是系统会自动生成的,只是R文件用于资源的id。图片我们就使用一个默认的

76180208_1.gif

1 packagecom.example.nanchen.databindingdemo;2

3 importandroid.databinding.DataBindingUtil;4 importandroid.os.Bundle;5 importandroid.support.v7.app.AppCompatActivity;6

7 importcom.example.nanchen.databindingdemo.databinding.ActivityDataBindingListBinding;8

9 importjava.util.ArrayList;10 importjava.util.List;11

12 public class DataBindingListActivity extendsAppCompatActivity {13

14 @Override15 protected voidonCreate(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 list = new ArrayList<>();21 for (int i = 0; i < 100; i++) {22 User user = newUser();23 user.setName("用户 " +i );24 user.setIcon("http://qlogo1.store.qq.com/qzone/503233512/503233512/100?1311741184");25 list.add(user);26 }27 CommonAdapter 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 }

76180208_1.gif

4)大概可以运行了哈。

76180208_3.png

5)如何添加点击事件呢?别慌,在我们的User中加入点击方法就好了。

76180208_1.gif

1 packagecom.example.nanchen.databindingdemo;2

3 importandroid.view.View;4 importandroid.widget.Toast;5

6 /**

7 * 继承,观察可刷新8 * Created by 南尘 on 16-7-18.9 */

10 public classUser {11 private String name;//用户名

12 private String nickName;//昵称

13 private String email;//邮箱

14

15 private boolean vip;//是否是会员

16 private int level;//级别

17 privateString icon;18

19 publicString getIcon() {20 returnicon;21 }22

23 public voidsetIcon(String icon) {24 this.icon =icon;25 }26

27 public intgetLevel() {28 returnlevel;29 }30

31 public void setLevel(intlevel) {32 this.level =level;33 }34

35 public booleanisVip() {36 returnvip;37 }38

39 public void setVip(booleanvip) {40 this.vip =vip;41 }42

43 publicUser() {44 }45

46 publicUser(String name, String nickName, String email) {47 this.name =name;48 this.nickName =nickName;49 this.email =email;50 }51

52 publicString getEmail() {53 returnemail;54 }55

56 public voidsetEmail(String email) {57 this.email =email;58 }59

60 publicString getName() {61 returnname;62

63 }64

65 public voidsetName(String name) {66 this.name =name;67 }68

69 publicString getNickName() {70 returnnickName;71 }72

73 public voidsetNickName(String nickName) {74 this.nickName =nickName;75 }76

77 public voidclickName(View view){78 Toast.makeText(view.getContext(),"点击了用户名:" +name,Toast.LENGTH_SHORT).show();79 }80

81 public booleanlongClickNickName(View view){82 Toast.makeText(view.getContext(),"长按了昵称:"+nickName,Toast.LENGTH_SHORT).show();83 return true;84 }85

86 public voidclick(View view){87 setName(getName() + "( 已点击 )");88 }89 }

76180208_1.gif

6)这里我们点击了用户2,什么情况?没刷新!!!!!,哦,哪里出了问题!

76180208_4.png

7)调皮的滑动了一下滚动条,再回去发现才刷新更改了。

76180208_5.png

9)e duo key,这里也太out了吧,说好的最屌框架呢?说好的要愉快一辈子呢?

仔细一看,才发现我们的逻辑中出了一点小问题,这样的话虽然你的list中的数据改变了,但是list并不知道,而这个adapter又没有刷新数据的方法,怎么办?

这里用到一个观察者模式,只需要把User继承BaseObservable类,并且在要更改的属性上加一个@Bindble,再在setName方法中加入这样一句话则可。

//刷新变量(变量id)

notifyPropertyChanged(com.example.nanchen.databindingdemo.BR.name);

76180208_1.gif

1 packagecom.example.nanchen.databindingdemo;2

3 importandroid.databinding.BaseObservable;4 importandroid.databinding.Bindable;5 importandroid.view.View;6 importandroid.widget.Toast;7

8 /**

9 * 继承,观察可刷新10 * Created by 南尘 on 16-7-18.11 */

12 public class User extendsBaseObservable {13 private String name;//用户名

14 private String nickName;//昵称

15 private String email;//邮箱

16

17 private boolean vip;//是否是会员

18 private int level;//级别

19 privateString icon;20

21 publicString getIcon() {22 returnicon;23 }24

25 public voidsetIcon(String icon) {26 this.icon =icon;27 }28

29 public intgetLevel() {30 returnlevel;31 }32

33 public void setLevel(intlevel) {34 this.level =level;35 }36

37 public booleanisVip() {38 returnvip;39 }40

41 public void setVip(booleanvip) {42 this.vip =vip;43 }44

45 publicUser() {46 }47

48 publicUser(String name, String nickName, String email) {49 this.name =name;50 this.nickName =nickName;51 this.email =email;52 }53

54 publicString getEmail() {55 returnemail;56 }57

58 public voidsetEmail(String email) {59 this.email =email;60 }61

62 @Bindable63 publicString getName() {64 returnname;65

66 }67

68 public voidsetName(String name) {69 this.name =name;70 //刷新变量(变量id)

71 notifyPropertyChanged(com.example.nanchen.databindingdemo.BR.name);72 }73

74 publicString getNickName() {75 returnnickName;76 }77

78 public voidsetNickName(String nickName) {79 this.nickName =nickName;80 }81

82 public voidclickName(View view){83 Toast.makeText(view.getContext(),"点击了用户名:" +name,Toast.LENGTH_SHORT).show();84 }85

86 public booleanlongClickNickName(View view){87 Toast.makeText(view.getContext(),"长按了昵称:"+nickName,Toast.LENGTH_SHORT).show();88 return true;89 }90

91 public voidclick(View view){92 setName(getName() + "( 已点击 )");93 }94 }

76180208_1.gif

10)再次运行:

76180208_6.png

现在好多了嘛,一点击就刷新了,是不是很吊?额,现在是点击整个item都可以刷新属性界面,好吧,其实无论你点击哪里,只要你加上这个click方法作为自定义属性,都可以实现这个功能,这里你要在原来的思路上实现是不是相当麻烦,而这个框架让你只需要移动一行代码的位置就可以,很高端大气上档次有木有?

这里做个示范,假如你是点击头像更改,只需要这样。

76180208_1.gif

1 <?xml version="1.0" encoding="utf-8"?>

2

3

5 xmlns:app="http://schemas.android.com/apk/res-auto">

6

7

8

10 type="com.example.nanchen.databindingdemo.User"/>

11

12

13

15 android:layout_height="match_parent"

16 android:orientation="horizontal"

17 >

18

19

21 android:layout_height="100dp"

22 app:imageUrl="@{user.icon}"

23 android:onClick="@{ user.click }"/>

24

25

27 android:layout_height="match_parent"

28 android:text="@{user.name}"

29 android:gravity="center"/>

30

31

32

76180208_1.gif

不仅可以放在这里,你还可以放在任何地方,无论是在ListView里面还是外面。

肯定这个框架还有其他的东西的,大家一起发掘咯~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值