android 数据绑定(1)Ativity、Fragment、Item绑定数据源
1.简介
官方文档:
https://developer.android.com/topic/libraries/data-binding
官方示例:
https://github.com/android/databinding-samples
作用:
把layout 与 数据对象关联,将layout上的组件与对象的成员绑定.让layout上的组件的值来自数据对象。如:
<TextView android:text="@{data.value}" />
2.简单用法:绑定Activity与数据源
2.1 打开绑定选项
只能在主module的 build.gradle 中打开,即使主module代码没有使用数据绑定,而他依赖的module使用了数据绑定,也要在主module中打开。
android {
...
dataBinding {
enabled = true
}
}
2.2 布局 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="data" type="com.example.databind.Data" /> <!--声明的对象data-->
<variable name="click" type="com.example.databind.Click" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout > <TextView android:text="@{data.value, default = value}" /> <!--值来自数据对象data-->
<Button android:onClick="@{() -> click.onStartClick(data)}" /> </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
其中
- 跟元素<layout> 包含 元素 <data>和 跟布局<ConstraintLayout >
- <data>元素用来定义layout使用的数据源,可以使用稍微复杂语法,如<import ...>,见第4、5行。
- layout上的组件使用@{数据源名.成员}指定值,@{}内可以使用简单的的绑定表达式,如第10行。
2.3 数据对象 Data.java
package com.example.databind;
public class Data {
public String key;
public int value;
public Data(String key, int value){
this.key = key;
this.value = value;
}
@Override
public String toString() {
return "key = " + key + " value = " + value;
}
}
2.4 建立绑定关系
package com.example.databind;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil; import com.example.databind.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding;
private Data data; private void init(){
data = new Data("time", );
binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main);
binding.setData(data);
binding.setClick(new Click(binding));
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
}
关于其中的 ActivityMainBinding :
- 第15行得到了把一个activity和一个布局关联,得到一个绑定对象 ActivityMainBinding,它是绑定框架生成的,见5。
- 写完layout后 Rebuild Project 一下 就可以生成它。
3. 绑定Fragment与数据源
3.1 布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<data >
<variable name="data" type="com.example.databind.Data" />
<variable name="click" type="com.example.databind.Click" />
</data> <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Hello Data Binding !"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /> <TextView
android:id="@+id/key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@{data.key, default = key}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/value"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintHorizontal_chainStyle="packed"
/> <TextView
android:id="@+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:text="@{String.valueOf(data.value),default = value}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/key"
app:layout_constraintTop_toTopOf="@+id/key" /> <Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:onClick="@{() -> click.onStartClick(data)}"
android:text="start"
android:textAllCaps="false"
app:layout_constraintEnd_toStartOf="@+id/stop"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/key" /> <Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:onClick="@{() -> click.onStopClicked(data)}"
android:text="stop"
android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="@+id/start"
app:layout_constraintEnd_toStartOf="@+id/reset"
app:layout_constraintStart_toEndOf="@+id/start"
app:layout_constraintTop_toTopOf="@+id/start" /> <Button
android:id="@+id/reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:text="reset"
android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="@+id/start"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/stop"
app:layout_constraintTop_toTopOf="@+id/start"
app:layout_constraintVertical_bias="1.0" /> <Button
android:id="@+id/list_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="list fragment"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stop" /> <EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintEnd_toEndOf="@+id/list_fragment"
app:layout_constraintStart_toStartOf="@+id/list_fragment"
app:layout_constraintTop_toBottomOf="@+id/list_fragment" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
3.2 数据类
Data.java
package com.example.databind;
public class Data {
public String key;
public int value;
public Data(String key, int value){
this.key = key;
this.value = value;
}
@Override
public String toString() {
return "key = " + key + " value = " + value;
}
}
click.java
package com.example.databind;
import android.util.Log;
import androidx.databinding.ViewDataBinding;
import java.util.Timer;
import java.util.TimerTask; public class Click {
ViewDataBinding binding;
private Timer timer; public void onStartClick(final Data data){
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (--data.value < ){
cancel();
return;
}
Log.e("ActivityMainBinding","data : " + data);
data.key = "left";
// binding.setData(data);
// binding.notifyChange();
// binding.notifyPropertyChanged(R.id.value);
// binding.value.invalidate();
if (!binding.hasPendingBindings()){
binding.invalidateAll();
}
}
}, * , * );
}
public void onStopClicked(Data data){
cancel();
}
private void cancel(){
if (timer != null){
timer.cancel();
timer = null;
}
}
public Click(ViewDataBinding binding){
this.binding = binding;
}
}
3.3 绑定
package com.example.databind; import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment; import butterknife.ButterKnife;
import butterknife.OnClick; public class MainFrgmt extends Fragment { ViewDataBinding binding;
private Data data; private void init(){
data = new Data("time", );
binding.setVariable(BR.data,data);
binding.setVariable(BR.click,new Click(binding));
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater,R.layout.frgmt_main,container,false);
View view = binding.getRoot();
ButterKnife.bind(this,view);
init();
return view;
} @OnClick(R.id.reset)
public void onResetClicked(View view){
data.key = "time";
data.value = ;
binding.invalidateAll();
}
}
其中:
- 第31行创建绑定对象 binding
- 第24、25行设置绑定的数据对象,其中的BR是绑定库生成的一个类,其中包含<data>中声明的变量的id。如data的id就是BR.data
- 第41行更新数据对象
4.Item绑定数据源
4.1 item布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"> <data>
<variable name="item" type="com.example.databind.list.ItemData" />
</data> <LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
app:imageSrc="@{item.icon}" />
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="5"
android:layout_marginLeft="32dp"
android:layout_marginStart="32dp"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
android:layout_gravity="center_vertical"
android:gravity="left|center_vertical"
android:textAllCaps="false"
android:textSize="16sp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="@{item.title,default = item}" />
</LinearLayout> </layout>
4.2 数据类
package com.example.databind.list;
public class ItemData {
public String title;
public int icon;
}
4.3 adapter
package com.example.databind.list; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import androidx.annotation.NonNull;
import androidx.databinding.BindingAdapter;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView; import com.example.databind.R;
import com.example.databind.databinding.ListItemBinding; import java.util.ArrayList;
import java.util.List; public class ListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<ItemData> datas = new ArrayList<>(); public void initData(){
for (int i = ; i < ; ++i){
ItemData item = new ItemData();
item.title = "item" + i;
switch (i){
case : case : case :
case : item.icon = R.mipmap.icon1; break; case : case : case :
case : item.icon = R.mipmap.icon2; break; case : case : case :
case : item.icon = R.mipmap.icon3; break; case : case : case :
case : item.icon = R.mipmap.icon4; break; case : case : case :
case : item.icon = R.mipmap.icon5; break; case : case :
case : item.icon = R.mipmap.icon6; break; case : case :
case : item.icon = R.mipmap.icon7; break; case : case :
case : item.icon = R.mipmap.icon8; break; case : case :
case : item.icon = R.mipmap.icon9; break;
default: item.icon = R.mipmap.icon0; break;
}
datas.add(item);
}
} @BindingAdapter({"imageSrc"})
public static void setImage(ImageView view, int icon){
view.setImageResource(icon);
} @NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.list_item,parent,false);
BindHolder holder = new BindHolder(view); return holder;
} @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
BindHolder bh = (BindHolder) holder;
ItemData item = datas.get(position);
ListItemBinding binding = DataBindingUtil.bind(bh.itemView);
binding.setItem(item);
} @Override
public int getItemCount() {
return datas.size();
} public static class BindHolder extends RecyclerView.ViewHolder{ public BindHolder(@NonNull View itemView) {
super(itemView);
}
}
}
5.ActivityMainBinding 等绑定类哪来的?
5.1 他们是绑定框架生成的接口
位置:
以 Frgmt1Binding 为例,它的实现在 : app\build\generated\ap_generated_sources\debug\out\com\example\databind\databinding 目录下,
com\example\databind 是包名,如下:

默认的命名规则:
布局文件名按Pascal命名方法(忽略下划线_) + Binding , 如布局文件是 Frgmt1.xml 那么生成的类就是 Frgmt1Binding
5.2 代码
package com.example.databind.databinding;
import com.example.databind.R;
import com.example.databind.BR;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.View;
@SuppressWarnings("unchecked")
public class Frgmt1BindingImpl extends Frgmt1Binding { @Nullable
private static final androidx.databinding.ViewDataBinding.IncludedLayouts sIncludes;
@Nullable
private static final android.util.SparseIntArray sViewsWithIds;
static {
sIncludes = null;
sViewsWithIds = new android.util.SparseIntArray();
sViewsWithIds.put(R.id.imageView, );
sViewsWithIds.put(R.id.textView, );
}
// views
@NonNull
private final androidx.constraintlayout.widget.ConstraintLayout mboundView0;
// variables
// values
// listeners
// Inverse Binding Event Handlers public Frgmt1BindingImpl(@Nullable androidx.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
this(bindingComponent, root, mapBindings(bindingComponent, root, , sIncludes, sViewsWithIds));
}
private Frgmt1BindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
super(bindingComponent, root,
, (android.widget.ImageView) bindings[]
, (android.widget.TextView) bindings[]
, (android.widget.TextView) bindings[]
, (android.widget.TextView) bindings[]
);
this.key.setTag(null);
this.mboundView0 = (androidx.constraintlayout.widget.ConstraintLayout) bindings[];
this.mboundView0.setTag(null);
this.value.setTag(null);
setRootTag(root);
// listeners
invalidateAll();
} @Override
public void invalidateAll() {
synchronized(this) {
mDirtyFlags = 0x4L;
}
requestRebind();
} @Override
public boolean hasPendingBindings() {
synchronized(this) {
if (mDirtyFlags != ) {
return true;
}
}
return false;
} @Override
public boolean setVariable(int variableId, @Nullable Object variable) {
boolean variableSet = true;
if (BR.click == variableId) {
setClick((com.example.databind.Click) variable);
}
else if (BR.data == variableId) {
setData((com.example.databind.Data) variable);
}
else {
variableSet = false;
}
return variableSet;
} public void setClick(@Nullable com.example.databind.Click Click) {
this.mClick = Click;
}
public void setData(@Nullable com.example.databind.Data Data) {
this.mData = Data;
synchronized(this) {
mDirtyFlags |= 0x2L;
}
notifyPropertyChanged(BR.data);
super.requestRebind();
} @Override
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
switch (localFieldId) {
}
return false;
} @Override
protected void executeBindings() {
long dirtyFlags = ;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = ;
}
java.lang.String stringValueOfDataValue = null;
java.lang.String dataKey = null;
com.example.databind.Data data = mData;
int dataValue = ; if ((dirtyFlags & 0x6L) != ) { if (data != null) {
// read data.key
dataKey = data.key;
// read data.value
dataValue = data.value;
} // read String.valueOf(data.value)
stringValueOfDataValue = java.lang.String.valueOf(dataValue);
}
// batch finished
if ((dirtyFlags & 0x6L) != ) {
// api target 1 androidx.databinding.adapters.TextViewBindingAdapter.setText(this.key, dataKey);
androidx.databinding.adapters.TextViewBindingAdapter.setText(this.value, stringValueOfDataValue);
}
}
// Listener Stub Implementations
// callback impls
// dirty flag
private long mDirtyFlags = 0xffffffffffffffffL;
/* flag mapping
flag 0 (0x1L): click
flag 1 (0x2L): data
flag 2 (0x3L): null
flag mapping end*/
//end
}
5.3 可以直接使用 ViewDataBinding
private ViewDataBinding binding;
private void init(View view){
binding = DataBindingUtil.bind(view);
MainActivity main = (MainActivity) getActivity();
binding.setVariable(BR.data,main.data);
}
android 数据绑定(1)Ativity、Fragment、Item绑定数据源的更多相关文章
- 【Android UI】:Fragment官方文档
概述 Fragment表现Activity中UI的一个行为或者一部分.可以将多个fragment组合在一起,放在一个单独的activity中来创建一个多界面区域的UI,并可以在多个activity ...
- Android开发-API指南-Fragment
Fragments 英文原文:http://developer.android.com/guide/components/fragments.html 采集日期:2014-12-31 在本文中 设计理 ...
- Android数据绑定技术一,企业级开发
PS:数据绑定,顾名思义是数据与一些控件或者用户账号等绑定,这样用的好处是便于管理.代码清晰,量少. 首先要了解什么是数据绑定? 为什么要用数据绑定? 怎么用数据绑定? 语法的使用 简单例子,数据绑定 ...
- Android数据绑定技二,企业级开发
PS:上一篇文章写了Databinding的简单使用,写了一个绑定textview的示例,和绑定的一些用法,估计有的人会说,之前的写的好好的,为什么要数据绑定这样的写法呢,没办法,社会在进步,当然是怎 ...
- Android开发工程师文集-Fragment,适配器,轮播图,ScrollView,Gallery 图片浏览器,Android常用布局样式
Android开发工程师文集-Fragment,适配器,轮播图,ScrollView,Gallery 图片浏览器,Android常用布局样式 Fragment FragmentManager frag ...
- Android数据绑定技术二,企业级开发
PS:上一篇文章写了Databinding的简单使用,写了一个绑定textview的示例,和绑定的一些用法,估计有的人会说,之前的写的好好的,为什么要数据绑定这样的写法呢,没办法,社会在进步,当然是怎 ...
- Android数据绑定DataBinding(一)入门篇
早上看到了一篇推文"还在使用繁琐的findViewById,跟着尝试了一下DataBinding,之前使用ButteKnife就已经干掉了findViewById.因为写过微信小程序,那种在 ...
- C# DataGridView绑定数据源的几种常见方式
开始以前,先认识一下WinForm控件数据绑定的两种形式,简单数据绑定和复杂数据绑定. 1. 简单的数据绑定 例1 using (SqlConnection conn = new SqlConnect ...
- wemall app商城源码Android 获取XML网络数据并绑定到ListView
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享Android 获取XML网络数据并绑定到Li ...
随机推荐
- 关于underline
1, 有些系统可能看不到下划线的效果,这是不妨按着Alt键看看: 2, underline=#, 数字表示在哪个字母下显示下划线,从0开始
- Zuul的过滤器
过滤器类型与请求生命周期: Zuul中定义了4种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期 PRE: 这种过滤器在请求被路由之前调用.可利用这种过滤器实现身 ...
- Javascript简单算法
1.多维数组取其所有第几个值组成新数组 例如 [[, , ], [, , ], [, , ]],我要标红的值 [[1, 3, 5], [2, 2, 2], [3, 3, 3]] let t = [[1 ...
- JavaScript中数组的集合和映射
集合 集合(set)是在ES6中引入的一种数据结构,用于表示唯一值的集合,所以它不能包含重复值.接 下来这一小节,就让我们具体来看一下这种新的数据结构. Set集合是一种无重复元素的列表,这是这种数据 ...
- WhaleCTF之隐写-Find
WhaleCTF之隐写-Find 前往题目 图片保存到本地,用Stegsolve打开图片 找到二维码 用微信或qq扫描,得到flag~
- js中读取json数据
1.JSON字符串转为JSON对象 var obj = eval('('+data+')');① var obj = data.praseJSON();② var obj = JSON.prase(d ...
- java扫描某个包下的所有java类并加载
最近在学习java的反射和注解,实际情景中需要扫描某个包下的所有java类,然后使用类加载器加载类. 基本思路,获得程序的路径扫描src下某个包内的子包和java类,实现也比较简单. 运行环境:win ...
- PKU--2184 Cow Exhibition (01背包)
题目http://poj.org/problem?id=2184 分析:给定N头牛,每头牛都有各自的Si和Fi 从这N头牛选出一定的数目,使得这些牛的 Si和Fi之和TS和TF都有TS>=0 F ...
- Df- Linux必学的60个命令
1.作用 df命令用来检查文件系统的磁盘空间占用情况,使用权限是所有用户. 2.格式 df [options] 3.主要参数 -s:对每个Names参数只给出占用的数据块总数. -a:递归地显示指定目 ...
- mybatis使用Example进行条件查询
参考: https://www.cnblogs.com/zhemeban/p/7183061.html Example类是什么? Example类指定如何构建一个动态的where子句. 表中的每个no ...