写点什么

Android 架构组件 JetPack 之 DataBinding 玩转 MVVM 开发实战(四)

用户头像
Android架构
关注
发布于: 刚刚

</layout>


注意 :※ 切记,在<layout>节点下是没有“layout_width”和“layout_height”的


※ type 中声明的就是我们的用户实体类 User,连同包名一定要写全!!!我们给其命名(name)为“user”,然后在 TextView 中的 @{user.name}就是把这个 user 中的名字展示出来,之后的“age””myBlog”同理


※ age 年龄在实体类 User 中我们定义的是整数类型,所以在布局中需要使用 String.valueOf(user.age)转换为字符串


一个 Binding 类会基于 layout 文件的名称而产生,并且添加“Binding”后缀。上述的 layout 文件是 main_basic.xml,因此生成的类名是 ActivityBasicBinding。通过 DataBindingUtil.setContentView 获取 bing 实例,进行数据绑定


public class BasicActivity extends Activity {


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityBasicBinding bing= DataBindingUtil.setContentView(this, R.layout.activity_basic);User user=new User("donkor",10,"http://blog.csdn.net/donkor_");bing.setUser(user);}}


运行之后看下效果图


2 . 显示照片


看完图之后,我们看下如何实现。我们选择用 glide 加载一张网络图片。glide 怎么在 studio 中使用,这里就不再讨论。如何显示一张网络图片,需要使用到 DataBinding 自定义属性 @BindingAdapter。在布局文件中使用这个自定义属性,显示出我们要展示的布局。还是那个实体类 User,添加自定义属性 @BindingAdapter({"imageUrl"})


public class User {public String imageUrl;


public User(String imageUrl){this.imageUrl=imageUrl;}


/**


  • 使用 ImageLoader 显示图片

  • @param imageView

  • @param url*/@BindingAdapter({"imageUrl"})public static void imageLoader(ImageView imageView, String url) {Glide.with(imageView.getContext()).load(url).into(imageView);}}


※ 这里要主要的是,imageLoader 方法必须声明是 static,否则会报错。


新建 activity_image.xml,因为使用了自定义属性,所以在 layout 节点下要添加 xmlns:app="http://schemas.android.com/apk/res-auto"。在 ImageView 中使用 app:imageUrl="@{user.imageUrl}"。完整代码如下:


<?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>


<variablename="user"type="com.donkor.demo.databinding.bean.User" />


</data>


<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">


<ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:imageUrl="@{user.imageUrl}" />


</LinearLayout>


</layout>


最后运行之后,结果如上图。我就不再发一遍了,有兴趣的朋友再拖回去看一遍,反正下面还有~~

3 . 更多用法

简单的字符拼接


<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{my Name is :+user.name}" />


<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:autoLink="all"android:text="@{my Blog is :+user.myBlog}" />


简单的三目运算判断名字是否为空,不为空只显示 user.name,否则显示 donkor11:


<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text='@{user.name ?? "donkor11"}' />


相当于


<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text='@{user.name !=null?user.name: "donkor11"}' />


这里需要注意的是当{}中使用了双引号“”,最外层要改成单引号”根据数据判断,显示数据判断是否为学生,是则显示 11,反则,显示 00


<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.isStudent?String.valueOf(11):String.valueOf(00)}" />


**修改样式 **判断是否为学生,是则修改背景颜色 0xFF0000FF,反则,显示 0xFFFF0000


<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@{user.isStudent?0xFF0000FF:0xFFFF0000}"android:text="donkor" />


写在之后的话,这里我们需要知道 Databinding 支持与不支持的表达式,语法。如下支持的表达式:1.Mathematical + - / * %2.String concatenation +3.Logical && ||4.Binary & | ^5.Unary + - ! ~6.Shift >> >>> <<7.Comparison == > < >= <=8.instanceof9.Grouping ()10.Literals - character, String, numeric, null11.Cast12.Method calls13.Field access14.Array access []15.Ternary operator ?:


不支持的表达式:1.this2.super3.new4.Explicit generic invocation 最后运行之后,看下效果图。


4 . 点击事件

单击事件单击事件在实际开发中,使用频率有多高这里就不解释了。下面我们直接看怎么用在 data 节点下的 variable 下 type 引用 android.view.View.OnClickListener。


<data><variablename="myClick"type="android.view.View.OnClickListener" /></data>


Button 按钮直接引用”myClick”


<Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="单击按钮"android:onClick="@{myClick}" />


长按事件长按事件的 button,首先需要分配一个 id 给 Button


<Buttonandroid:id="@+id/btnLongClick"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="长按按钮"/>


在 Activity 中,使用数据绑定,直接引用按钮 id。完整代码如下


public class ClickActivity extends Activity {


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityClickBinding bing=DataBindingUtil.setContentView(this, R.layout.activity_click);


//事件绑定 -- 单击 bing.setMyClick(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(ClickActivity.this,"发生了点击事件",Toast.LENGTH_SHORT).show();}});


//事件绑定 -- 长按 bing.btnLongClick.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {Toast.makeText(ClickActivity.this,"发生了长按事件",Toast.LENGTH_SHORT).show();return false;}});}}


最后运行之后,看下效果图。



▲5 . 绑定 ListViewListview 在实际开发中使用频率同样很高,看了上面那么多例子。就知道 Databinding 绑定 ListView 一样简单。接下来看一组美图。



看完之后,能看出布局其实就是一张 ImageView,底下加一个 TextView。例子很简单 ,然后看下如何实现。首先需要新建一个美女的实体类,我们先定义 Beauty,beautyNum 就是美女底下的 TextView 文本。


public class Beauty {public String beautyNum;public String imageUrl;


public Beauty(String beautyNum, String imageUrl) {this.beautyNum = beautyNum;this.imageUrl = imageUrl;}


@BindingAdapter({"imageUrl"})public static void beautyImage(ImageView imageView, String url) {Glide.with(imageView.getContext()).load(url).into(imageView);}}


然后看下主布局 activity_listview.xml,在 data 节点下的 variable 下 type 引用 android.widget.BaseAdapter。


<?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>


<variablename="adapter"type="android.widget.BaseAdapter" /></data>


<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent">


<ListViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:adapter="@{adapter}" /></LinearLayout></layout>


然后 ListView 的 item 布局 item_listview.xml,同样比较简单,在这不做解释。


<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.and


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


roid.com/apk/res-auto">


<data><variablename="beauty"type="com.donkor.demo.databinding.bean.Beauty" /></data>


<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">


<ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:imageUrl="@{beauty.imageUrl}" />


<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{beauty.beautyNum}" />


</LinearLayout>


</layout>


有 ListView 的地方,十有八九就有适配器。这里介绍一个终极适配器的写法 MyBaseAdapter。尽管这里仅仅是给美女使用的适配器,但是已经说明了是终极写法。我们就不叫它美女适配器了。


public class MyBaseAdapter<T> extends BaseAdapter {


private List<T> list;private int layoutId;private int variableId;private LayoutInflater mInflater;


public MyBaseAdapter(Context context, List<T> list, int layoutId, int variableId) {this.list = list;this.layoutId = layoutId;this.variableId = variableId;this.mInflater = LayoutInflater.from(context);}


@Overridepublic int getCount() {return list.size() == 0 ? 0 : list.size();}


@Overridepublic Object getItem(int position) {return list.get(position);}


@Overridepublic long getItemId(int position) {return position;}


@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewDataBinding dataBinding;if (convertView == null) {dataBinding = DataBindingUtil.inflate(mInflater, layoutId, parent, false);} else {dataBinding = DataBindingUtil.getBinding(convertView);}dataBinding.setVariable(variableId, list.get(position));


return dataBinding.getRoot();}}


然后解释下其中几个变量


Context context:上下文,不比多说 List list:传进来的数据集合,不解释 int layoutId: item 布局的资源 idint variableId:系统自动生成的※ 注意布局加载方式为 DataBindingUtil 类中的 inflate 方法最后看下 ListViewActivity 完整代码


public class ListViewActivity extends Activity {private List<Beauty> list;


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityListviewBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_listview);


list = new ArrayList<>();//加载数据 initData();


MyBaseAdapter<Beauty> adapter = new MyBaseAdapter<>(ListViewActivity.this, list, R.layout.item_listview, BR.beauty);binding.setAdapter(adapter);}


void initData() {Beauty beauty1 = new Beauty("第一个美女", "http://img2.imgtn.bdimg.com/it/u=3988249408,1489015532&fm=21&gp=0.jpg");Beauty beauty2 = new Beauty("第二个美女", "http://img4.imgtn.bdimg.com/it/u=2579627311,3580753633&fm=21&gp=0.jpg");Beauty beauty3 = new Beauty("第三个美女", "http://img5.imgtn.bdimg.com/it/u=539171541,1245868076&fm=23&gp=0.jpg");Beauty beauty4 = new Beauty("第四个美女", "http://img1.imgtn.bdimg.com/it/u=3494499027,4116428522&fm=23&gp=0.jpg");Beauty beauty5 = new Beauty("第五个美女", "http://img4.imgtn.bdimg.com/it/u=645329305,336210525&fm=23&gp=0.jpg");list.add(beauty1);list.add(beauty2);list.add(beauty3);list.add(beauty4);list.add(beauty5);}}


最后运行之后,结果如上图。有兴趣的朋友再拖回去看一遍,反正下面没有美女了~~

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)