Skip to content

RobbeSneyders/Modular2Recycler

Repository files navigation

Header

Modular²Recycler is a RecyclerView.Adapter that is modular squared.

It also adds extra features:

  • OnItem(Long)ClickListener
  • Headers
  • Swipe to dismiss with undo
  • Drag and drop.

Item clickItem clickItem clickItem click

Design Pattern

This library uses the approach of Modular design, in which a system is subdivided into modular, reusable components. A detailed explanation about the architecture of this library can be read here.

The ² in Modular²Recycler denotes the modularity of the adapter on two separate levels.

First Level

Instead of creating one huge adapter to populate a RecyclerView with data, one AdapterModule is created for each different viewtype.

Modular level 1

Second Level

Extra funcionality can be added to these AdapterModules by implementing plugins provided by this library.

Modular level 2

Dependencies

This libary can be added to your project by using JitPack.

Add Jitpack in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Add this library as dependency to your project:

dependencies {
        compile 'com.github.RobbeSneyders:Modular2Recycler:v1.0.2'
}

How to use

This library does a lot of the necessary work for you. Just follow these steps:
Example based on available example app.

1. For each ViewType

  • Create an item by implementing ModularItem
  • Create a module by extending AdapterModule

Pokemon & PokemonModule

public class Pokemon implements ModularItem {
    public String name;
    public Drawable icon;
    
    public boolean isHeader() {
        return false;
    }
}

class PokemonModule extends AdapterModule<PokemonViewHolder, Pokemon> {

    @Override
    public PokemonViewHolder onCreateViewHolder(ViewGroup parent) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_row, parent, false);
        return new PokemonViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(PokemonViewHolder viewHolder, Pokemon pokemon) {
        viewHolder.vText.setText(pokemon.name);
        viewHolder.vIcon.setImageDrawable(pokemon.icon);
    }

    public static class PokemonViewHolder extends RecyclerView.ViewHolder {
        public ImageView vIcon;
        public TextView vText;

        public PokemonViewHolder(View view) {
            super(view);
            vText = (TextView) view.findViewById(R.id.textView);
            vIcon = (ImageView) view.findViewById(R.id.imageView);
        }
    }    
}

Header & HeaderModule

public class Header implements ModularItem {
    String name;

    public Header(String name) {
        this.name = name;
    }
    
    public boolean isHeader() {
        // return true to make ModularAdapter recognize this as a header class.
        return true;
    }
}

class HeaderModule extends AdapterModule<HeaderModule.HeaderViewHolder, Header> {

    @Override
    public HeaderViewHolder onCreateViewHolder(ViewGroup parent) {
        View headerView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_header, parent, false);
        return new HeaderViewHolder(headerView);
    }

    @Override
    public void onBindViewHolder(HeaderViewHolder viewHolder, Header header) {
        viewHolder.vText.setText(header.name);
    }

    static class HeaderViewHolder extends ViewHolder {
        TextView vText;

        HeaderViewHolder(View view) {
            super(view);
            vText = (TextView) view.findViewById(R.id.textView);
        }
    }
}

2. Add the desired functionality to your module by implementing the corresponding plugins.

public class PokemonModule extends AdapterModule<PokemonViewHolder, Pokemon>
    implements ItemClickPlugin, ItemLongClickPlugin {

    // AdapterModule Methods
    ...

    @Override
    public void onItemClicked(Pokemon pokemon) {
        // Item clicked
    }

    @Override
    public boolean onItemLongClicked(Pokemon pokemon) {
        // Item long clicked
        return true;
    }

3. Create an instance of the ModularAdapter in your Activity

There is no need to extend the ModularAdapter class unless you want to add extra functionality.

List<Pokemon> pokemonList = Pokedex.getAllPokemonAlphabetic();
List<ModularItem> list = addHeaders(pokemonList);

adapter = new ModularAdapterBuilder<>(recyclerView, list)
        .setSwipeLeft(Color.RED, ResourcesCompat.getDrawable(getResources(), R.drawable.ic_delete_white_24dp, null))
        .setSwipeRight(Color.GREEN, ResourcesCompat.getDrawable(getResources(), R.drawable.ic_cloud_upload_white_24dp, null))
        .build();

4. Create an instance of the AdapterModules you want to add and bind them to the created instance of ModularAdapter

new PokemonModule().bindToAdapter(adapter);
new HeaderModule().bindToAdapter(adapter);

Example App

PokéApp is an example app to demonstrate the use of this library.

UndoRecycler UndoRecyclerAlphabetic

Other apps using this library

Swipe Shortcuts Widget

Contributing

Contributions in any way are greatly appreciated.

License

Code released under the Apache license.