Skip to content

An Android library, which (extremely) simplifies seeding lists with data

License

Notifications You must be signed in to change notification settings

PGSSoft/ForgetAdapters

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pgssoft-logo.png

ForgetAdapters

An Android library, which (extremely) simplifies seeding lists with data

No more adapters. You're gonna love this.

Introduction

Implementing lists in Android requires much boilerplate code. Each time you create new list, you need to create a new adapter, which seeds that list with data. Fortunately, since Google introduced Data Binding Library, this process may be simplified. A lot.

We dare say, that we bring that boilerplate code to absolute minimum (minus code you'd have to write anyway). Catch? We assume, that the application is being written according to MVVM pattern.

With our library you will be able to display list with the following code:

    <android.support.v7.widget.RecyclerView
        android:id="@+id/m_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:items="@{viewModel.people}"
        app:viewProvider="@{viewProvider}"/>

app:items allows you to provide an ObservableArrayList with data and app:viewProvider - a ViewProvider object, which will instantiate views for list items.

You can find a complete tutorial below.

How to use

TODO - add jitpack/maven link

Keep in mind, that this is a complete tutorial how to implement displaying list in MVVM Android application with our library. The actual boilerplate code does not exceed 10 lines.

Create a model you want to display

First of all, let's create a model, which will populate our list.

public class PersonModel {

    private String name;
    private String surname;
    private String company;

    public PersonModel() {

    }

    public PersonModel(String name, String surname, String company) {

        this.name = name;
        this.surname = surname;
        this.company = company;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }
}

MVVM Activity

Create MVVM activity with convigured viewmodel and bindings. You can do that simply with our Android MVVM templates.

Activity code may look like following:

public class MainActivity extends AppCompatActivity implements IMainActivityAccess {

    // Private fields ---------------------------------------------------------

    private ActivityMainBinding binding;
    private MainActivityViewModel viewModel;

    // Protected methods ------------------------------------------------------

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        viewModel = new MainActivityViewModel(this);
        binding.setViewModel(viewModel);
    }
}

Create list of models

We need a list in which we will keep our models. ObservableArrayList allows the binding library track changes to list's items.

public class MainActivityViewModel extends BaseObservable {

    // Private fields ---------------------------------------------------------

    private IMainActivityAccess access;
    private ObservableArrayList<PersonModel> people;

    public MainActivityViewModel(IMainActivityAccess access) {

        this.access = access;

        people = new ObservableArrayList<>();
        people.add(new PersonModel("Wojciech", "Sura", "PGS Software S.A."));
        people.add(new PersonModel("Bill", "Gates", "Microsoft"));
        people.add(new PersonModel("Steve", "Jobs", "Apple"));
    }
	
    public ObservableArrayList<PersonModel> getPeople() {
        
        return people;
    }	
}

View for displaying model

We need to define, how a single item will look on the list. For that, create a MVVM View (Android MVVM templates provides a template for that as well)

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

    <data>

        <variable
            name="viewModel"
            type="com.pgssoft.forgetAdaptersDemo.viewmodels.PersonViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@{viewModel.name}"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@{viewModel.surname}"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@{viewModel.company}"/>

    </LinearLayout>
</layout>

Obviously, we need to provide appropriate values for bound fields, so let's fill view's viewmodel:

public class PersonViewModel extends BaseObservable {

    // Private fields ---------------------------------------------------------

    private IPersonViewAccess access;
    private final ObservableField<String> name;
    private final ObservableField<String> surname;
    private final ObservableField<String> company;

    // Public methods ---------------------------------------------------------

    public PersonViewModel(IPersonViewAccess access) {

        this.access = access;
        name = new ObservableField<String>();
        surname = new ObservableField<String>();
        company = new ObservableField<String>();
    }
    
    // Public properties ------------------------------------------------------

    public ObservableField<String> getName() {
        return name;
    }

    public ObservableField<String> getSurname() {
        return surname;
    }

    public ObservableField<String> getCompany() {
        return company;
    }
}

Attaching data source

So far we wrote only code, which needs to be written anyway. Let's now use our ForgetAdapters library. Place RecyclerView on the activity.

(...)
    <data>

        <variable
            name="viewModel"
            type="com.pgssoft.forgetAdaptersDemo.viewmodels.MainActivityViewModel" />
        <variable
            name="viewProvider"
            type="com.pgssoft.forgetadapters.dataBinding.RecyclerViewProvider" />
    </data>

(...)

        <android.support.v7.widget.RecyclerView
            android:id="@+id/m_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:items="@{viewModel.people}"
            app:viewProvider="@{viewProvider}"/>

This is the way we provide RecyclerView with data source (app:items) and a way to generate views (app:viewProvider). Since ViewModel already provides ObservableArray with our models through people property, we only need to implement the ViewProvider.

Don't forget to set LayoutManager or otherwise RecyclerView won't show anything.

public class MainActivity extends AppCompatActivity implements IMainActivityAccess {

    (...)

    private RecyclerViewProvider<PersonModel, PersonView> viewProvider = new RecyclerViewProvider<PersonModel, PersonView>() {
        @Override
        public PersonView createView(int viewType) {
            return new PersonView(MainActivity.this);
        }
    };
	
	(...)
	
	@Override
    protected void onCreate(Bundle savedInstanceState) {

		(...)
        binding.setViewProvider(viewProvider);
        binding.mList.setLayoutManager(new LinearLayoutManager(this));
		(...)
    }

Some additional changes

ViewProvider works correctly, when provided view can give access to its viewmodel. We can do that by implementing IDataViewModelProvider in our PersonView:

public class PersonView extends FrameLayout implements IPersonViewAccess, IDataViewModelProvider<PersonModel> {

(...)

    @Override
    public IDataViewModel<PersonModel> getViewModel() {
        return viewModel;
    }
}

Also, view's viewmodel needs to provide a way to be filled with provided model. We can do that by implementing IDataViewModel in view's viewmodel.

public class PersonViewModel extends BaseObservable implements IDataViewModel<PersonModel> {

    (...)

    @Override
    public void setData(PersonModel data) {
        name.set(data.getName());
        surname.set(data.getSurname());
        company.set(data.getCompany());
    }
}

Run the application

This is all - we can now run the application and see list's contents displayed in the RecyclerView. What's important, all changes in the underlying ObservableArrayList will be automatically transferred to the activity.

What's most important, no adapters were written during writing this demo application. We also managed to push boilerplate code to the absolute minimum: additional attributes in layout (2 lines), implementation of ViewProvider (6 lines) and setting it in activity (1 line).

If you don't like RecyclerView, very similar mechanism is ready for ListView - just use ListViewProvider instead.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/PGSSoft/ForgetAdapters.

License

The project is available as open source under the terms of the MIT License.

About

The project is maintained by software development agency PGS Software. See our other open-source projects or contact us to develop your product.

Follow us

Twitter URL
Twitter Follow

About

An Android library, which (extremely) simplifies seeding lists with data

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages