The Data Binding Library provides both flexibility and wide compatibility — it’s a support library, so you can use it on systems running Android 4.0 (API level 14) or greater. The example to show how to use data binding with RecyclerView displays a list of item in RecyclerView
To configure your app to use data binding, add the data binding component to the build. Gradle file in the app module Also add the recycler view dependencies and sync the project.
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.materialuiux.databindingexample"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
}
Create an item layout that declares the item object to be a data binding variable, then bind the item properties to the Views attributes in the item layout using a data binding expression.
item_post_view.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable name="iclick" type="com.materialuiux.databindingexample.IClick"/>
<variable
name="post"
type="com.materialuiux.databindingexample.model.Post" />
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> iclick.onClicked(post)}"
android:orientation="vertical">
<TextView
android:id="@+id/tilte"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{post.title}"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@{post.body}"
android:textSize="14sp"
android:textStyle="normal" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="1dp"
android:background="#d2d2d2" />
</LinearLayout>
</layout>
and now create adapter for the Recyclerview
Ad_Recycler_View.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.materialuiux.databindingexample.databinding.ItemPostViewBinding;
import com.materialuiux.databindingexample.model.Post;
import java.util.List;
public class Ad_Recycler_View extends RecyclerView.Adapter<Ad_Recycler_View.ViewHolder> implements IClick {
private List<Post> data;
private Context mContext;
private LayoutInflater layoutInflater;
Ad_Recycler_View(List<Post> dummyData, Context context) {
this.data = dummyData;
this.mContext = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (layoutInflater == null) {
layoutInflater = LayoutInflater.from(parent.getContext());
}
ItemPostViewBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.item_post_view, parent, false);
return new ViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.setData(data.get(position));
holder.binding.setIclick(this);
}
@Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ItemPostViewBinding binding;
ViewHolder(final ItemPostViewBinding itemBinding) {
super(itemBinding.getRoot());
this.binding = itemBinding;
}
void setData(Post post) {
binding.setPost(post);
binding.executePendingBindings();
}
}
public void onClicked(Post post) {
Toast.makeText(mContext, "You clicked " + post.getBody(), Toast.LENGTH_LONG).show();
}
}
In order to pass the data to the XML counterpart we bind it using binding.setPost(post);
Executependingbindings() is important in order to execute the data binding immediately. Otherwise, it can populate the incorrect view.
in case you want to implement onClick we need to create an interface and attached to the adapter
IClick.java
import com.materialuiux.databindingexample.model.Post; public interface IClick { void onClicked(Post post); }
Post.java
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
public class Post extends BaseObservable {
String title;
String body;
public Post(String title, String body) {
this.title = title;
this.body = body;
}
@Bindable
public String getTitle() {
return title;
}
@Bindable
public String getBody() {
return body;
}
}
Create layout XML inside the <layout/>.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" />
</LinearLayout>
</layout>
Replace traditional setContentView() with DataBindingUtil.setContentView()
1- create a databindingutils class object, and replace the traditional setcontentview() with databindingutil. Setcontentview() .
2- initializes the RecyclerView with sample data and attach the adapter to the Recycler View .
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.os.Bundle;
import com.materialuiux.databindingexample.databinding.ActivityMainBinding;
import com.materialuiux.databindingexample.model.Post;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.recyclerview.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerview.addItemDecoration(
new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
Ad_Recycler_View adapter = new Ad_Recycler_View(getDummyData(), this);
binding.recyclerview.setAdapter(adapter);
}
private List<Post> getDummyData() {
List<Post> list = new ArrayList<>();
for (int i = 0 ; i < 20 ; i++){
list.add(new Post("title " + i, "body " + i));
}
return list;
}
}
that’s it, Get the full Example from Github