SlideShare a Scribd company logo
Data binding to the
rescue... or not (?)
KRISTIJAN JURKOVIC
WHAT IS DATA BINDING?
• Process that establishes a connection between the
application UI and Business logic.
• UI reflects data changes when made
• Announced on the Google I/O 2015
REQUIREMENTS
• API level 7+ (Android 2.1 Eclair)
• Android Studio with Android Gradle plugin 1.3.0-beta4 or
higher
• Data binding lib (currently RC)
SETUP
Top level build.gradle
dependencies {

classpath 'com.android.tools.build:gradle:1.3.0'

classpath 'com.android.databinding:dataBinder:1.0-rc1'

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
SETUP
App module build.gradle
dependencies {

...

apt 'com.android.databinding:compiler:1.0-rc0'

}
apply plugin: 'com.android.databinding'

apply plugin: 'com.neenbedankt.android-apt'
01THE CODE
BIND IT
• Several ways of binding:
• DataBindingUtil.setContentView({activity}, {layout});
• DataBindingUtil.bind({view});
• DataBindingUtil.inflate({inflater}, {layout}, {parentView},
{attachToParent});
WHAT DO WE GET?
• Data binding lib will generate object with name of your
layout in camel case, suffixed with Binding
• list_item_film.xml → ListItemFilmBinding
• on that object we can set variables which are defined in our
layout
<?xml	version="1.0"	encoding="utf-8"?>	
<layout	xmlns:android="http://schemas.android.com/apk/res/android">	
				<data>	
								<variable	name="film"	type="co.infinum.starwars.models.Film"/>	
				</data>	
				<LinearLayout	
												android:layout_width="match_parent"	
												android:layout_height="match_parent"	
												android:orientation="vertical">	
								<TextView	
																android:id="@+id/title"	
																android:layout_width="match_parent"	
																android:layout_height="wrap_content"	
																android:text="@{film.getTitle()}"	
																android:padding="@dimen/default_spacing"/>	
								<TextView	
																android:id="@+id/director"	
																android:layout_width="match_parent"	
																android:layout_height="wrap_content"	
																android:text="@{film.getDirector()}"	
																android:padding="@dimen/default_spacing"/>	
								<TextView	
																android:id="@+id/description"	
																android:layout_width="match_parent"	
																android:layout_height="wrap_content"	
																android:text="@{film.getDescription()}"	
																android:padding="@dimen/default_spacing”/>	
				</LinearLayout>	
</layout>
public	class	FilmDetailsActivity	extends	BaseActivity	{	
				public	static	final	String	FILM	=	"film";	
				private	ActivityDetailsBinding	binding;	
				private	Film	film;	
				@Override	
				protected	void	onCreate(Bundle	savedInstanceState)	{	
								super.onCreate(savedInstanceState);	
								binding	=	DataBindingUtil	
																			.setContentView(this,	R.layout.activity_details);	
								film	=	(Film)	getIntent().getSerializableExtra(FILM);	
								binding.setFilm(film);	
				}	
}
WHATS WITH THE LISTS
• You can inflate the view in adapter same as in Fragment
• ViewHolder is a bit different that it used to be
<?xml	version="1.0"	encoding="utf-8"?>	
<layout	xmlns:android="http://schemas.android.com/apk/res/android">	
				<data>	
								<variable	name="film"		
																type="co.infinum.starwars.models.Film"	/>	
				</data>	
				<TextView	
												android:id="@+id/name"	
												android:layout_width="match_parent"	
												android:layout_height="wrap_content"	
												android:text="@{film.getTitle()}"	
												android:padding="@dimen/default_spacing"/>	
</layout>
public	class	FilmsAdapter		
							extends	RecyclerView.Adapter<FilmsAdapter.ViewHolder>	{	
				
				{	some	code	here	}	
				@Override	
				public	FilmsAdapter.ViewHolder		
																onCreateViewHolder(ViewGroup	parent,	int	viewType)	{	
								ListItemMovieBinding	binding	=		
																		DataBindingUtil.inflate(	
																									LayoutInflater.from(context),		
																									R.layout.list_item_movie,		
																									parent,	false);	
								return	new	ViewHolder(binding,	listener);	
				}	
				@Override	
				public	void	onBindViewHolder(	
FilmsAdapter.ViewHolder	holder,	int	position)	{	
								holder.getBinding().setFilm(getItem(position));	
				}		
{	some	code	here	}	
}
public	static	class	ViewHolder		
							extends	RecyclerView.ViewHolder		
							implements	View.OnClickListener	{	
								private	ListItemMovieBinding	binding;	
								private	OnItemClickListener	listener;	
								ViewHolder(ListItemMovieBinding	binding,		
OnItemClickListener	listener)	{	
												super(binding.getRoot());	
												this.binding	=	binding;	
												this.listener	=	listener;	
												binding.getRoot().setOnClickListener(this);	
								}	
								@Override	
								public	void	onClick(View	v)	{	
												if	(listener	!=	null)	{	
																listener.onItemClick(getAdapterPosition());	
												}	
								}	
								public	ListItemMovieBinding	getBinding()	{	
												return	binding;	
								}	
				}
public	class	Film	extends	BaseObservable	{	
				{some	code}	
				@SerializedName("title")	
				private	String	title;	
				@Bindable	
				public	String	getTitle()	{	
								return	title;	
				}	
				public	void	setTitle(String	title)	{	
								this.title	=	title;	
								notifyPropertyChanged(BR.title);	
				}	
				{some	code}	
}
public	class	Film	{	
				private	final	ObservableField<String>	title	=	new	ObservableField<>();	
}
01IS IT ALL THERE IS?
NO IT IS NOT
• ObservableCollections
• Event Bindings (OnClick, OnLongClick, etc)
• Dynamic Bindings (for the adapters)
• Custom Setters (for properties which do not have same
name as methods in Java - e.g. padding)
DYNAMIC BINDINGS
@Override	
public	void	onBindViewHolder(FilmsAdapter.ViewHolder	holder,	int	position)	{	
			final	T	item	=	items.get(position);	
			holder.getBinding().setVariable(BR.item,	item);	
			holder.getBinding().executePendingBindings();	
}
CUSTOM SETTERS
@BindingAdapter("app:imageUrl")	
public	static	void	loadImage(ImageView	view,	String	url)	{	
	 Glide.with(context).load(url).into(view);	
}
<layout>	
	 <data>	
	 				<variable	name="binder"	type="com.example.feed.DummyBinder"	/>	
	 </data>	
				<LinearLayout	
								android:layout_width="match_parent"	
								android:layout_height="wrap_content"	
								android:orientation="vertical">	
								<ImageView	
												android:layout_width="match_parent"	
												android:layout_height="wrap_content"	
												app:imageUrl="@{binder.imageUrl}"	/>	
				</LinearLayout>	
</layout>
SHOULD WE USE IT?
• You can, on your own risk. - Why?, you ask.
• RC release
• Might contain bugs
• Subject to significant changes which might not be
compatible with your app
• without APT - AS can’t find generated classes
HOW SHOULD WE USE IT?
• Databinding allows some kind of logic in layouts
• Databinding allows various imports in the layouts
• Be smart - don’t do it or you’ll have bonding time with AS
debugger when output is not what you desire
WHAT TO READ?
• http://developer.android.com/tools/data-binding/
guide.html#custom_binding_class_names
• https://realm.io/news/data-binding-android-boyar-mount/
• https://www.reddit.com/r/androiddev/comments/3f9c3v/
android_data_binding_moves_some_logic_to_xml_is/
• https://code.google.com/p/android/issues/list?can=2&q=Data
+binding&colspec=ID+Type+Status+Owner+Summary
+Stars&cells=tiles
EXAMPLES
• https://github.com/kjurkovic/Hello-Databinding
• https://github.com/ikocijan/Hello-data-binding
Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Kristijan Jurkovic
Thank you!
Visit www.infinum.co or find us on social networks:
infinum.co infinumco infinumco infinum

More Related Content

Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Kristijan Jurkovic