easydatabinding

Additional

Language
Java
Version
0.6.0 (Aug 9, 2016)
Created
Apr 13, 2016
Updated
Aug 2, 2017 (Retired)
Owner
joxad
Contributor
joxad
1
Activity
Badge
Generate
Download
Source code

easydatabinding

This project goal is to create activity fragment and views, with less code to be more efficient on the view models

Version : 1.1.0

Goal

I used DataBinding for a few weeks since Google allows us to use it.

For now i saw a lot of duplicated code to instantiate an activity or a fragment. So I make this library to avoid boilerplate, and you will be able to focus on your code .

Thanks

Very useful lib used in easydatabinding :

https://github.com/evant/binding-collection-adapter/

If you want to use it without easydatabinding , just add this compile "me.tatarka.bindingcollectionadapter2:bindingcollectionadapter:2.0.1" compile "me.tatarka.bindingcollectionadapter2:bindingcollectionadapter-recyclerview:2.0.1"

It handles the databinding inside the recyclerview => No adapter to write :)

Side project very usefull if you are lazy (I am)

https://github.com/joxad/generator-android-template

If you know yeoman, you won't be surprised. It is a generator that will help you create the activity/vm data (see below and the sample for more details)

How to use it

It requires at least android gradle plugin 2.3.0.

Gradle root :

repositories {
    maven {
        url  "http://dl.bintray.com/joxad/maven"
    }
}

Gradle project :

compile "com.joxad.easydatabinding:lib:$currentVersion"

Fast Sample

With the library an activity will be :

public class ActivityMain extends ActivityBase<ActivityMainBinding,ActivityMainVM> {

    @Override
    public int data() {
        return BR.activityMainVM;
    }

    @Override
    public int layoutResources() {
        return R.layout.activity_main;
    }

    @Override
    public ActivityMainBaseVM baseActivityVM(ActivityMainBinding binding) {
        return new ActivityMainVM(this, binding);
    }

}

And your VM :

public class ActivityMainVM extends ActivityBaseVM<ActivityMain, ActivityMainBinding> {

    /***
     * This is the itemView view that will put the user in the
     */
    public ItemBinding<PeopleVM> itemView = ItemBinding.of(peopleVM, item_people);

    public ObservableArrayList<PeopleVM> items;

    /***
     * @param activity
     * @param binding
     */
    public ActivityMainVM(ActivityMain activity, ActivityMainBinding binding) {
        super(activity, binding);
    }

    @Override
    public void onCreate() {

        StarWarsApi.INSTANCE.init(activity);
        items = new ObservableArrayList<>();



    }

    @Override
    public void onResume() {
        super.onResume();
        items.clear();
        StarWarsApi.INSTANCE.people().enqueue(new Callback<PeopleResult>() {
            @Override
            public void onResponse(Call<PeopleResult> call, Response<PeopleResult> response) {
                for (Result people : response.body().getResults()) {
                    items.add(new PeopleVM(activity, people).setOnSelected(new PeopleVM.OnSelected() {
                        @Override
                        public void people(Result people) {
                            goToActivityPeople(people);
                        }
                    }));
                }
            }

            @Override
            public void onFailure(Call<PeopleResult> call, Throwable t) {
                Log.d(ActivityMain.class.getSimpleName(), t.getLocalizedMessage());
            }
        });
    }

    private void goToActivityPeople(Result people) {
        activity.startActivity(new Intent(activity, ActivityPeople.class).putExtra(Extra.PEOPLE, people));
    }
}

You will need a layout :

<?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"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="me.tatarka.bindingcollectionadapter2.LayoutManagers" />

        <variable
            name="activityMainVM"
            type="joxad.easydatabinding.sample.home.ActivityMainVM" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".home.ActivityMainVM">

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:itemView="@{activityMainVM.itemView}"
            app:items="@{activityMainVM.items}"
            app:layoutManager="@{LayoutManagers.linear()}" />
    </RelativeLayout>
</layout>

WTF : you have two classes ??? Why don't you put all the logic in the ActivityBase / FragmentBase ?

Well, in order to use the databinding, the classes that will handle the view must extends BaseObservable, and in some cases, some data needs to be visible only in this unique fragment.

So the activity now become a way to access the views (with the bindings) and the VM class will handle all the treatments.

More

  • See the package sample in order to see in working with a API using retrofit. I used https://swapi.co/ for sample.

  • To handle Result there are useful interfaces you can put in your VM's class of your activity

For example, you can implement :

IPermission //handle permission result from android 5.0+ 
IResult // handle the result from another activity
INewIntent // called when activity receives a new intent
  • Handler

All the ActivityBaseVM/FragmentBaseVM have 2 handler :

  • uiHandler to handle runnable to do tasks on the uiThread (like showToast on a callback from a WS)
  • handler classic to create runnable on the fly

Notes about the DataBinding

  • Each Activity or Fragment is linked to a viewmodel who will expose the data to the view (layout) and handle some specific fucntionnalities

  • ViewModel will also handle some treatments :

    • WS Calls . Database to update the recyclerview of the layout
    • activityresult of activity (for facebook . google login for example)