Adapster

Additional

Language
Java
Version
N/A
Created
Aug 1, 2018
Updated
Sep 9, 2018
Owner
Arthur Ivanets (arthur3486)
Contributor
Arthur Ivanets (arthur3486)
1
Activity
Badge
Generate
Download
Source code
APK file

Announcement

Adapster

Android library designed to enrich and make your RecyclerView adapters more SOLID

Adapster will help you make your RecyclerView adapters more manageable and overall enrich your RecyclerView epxerience.

Contents

Demo (YouTube)

Getting Started

  1. Make sure that you've added the jcenter() repository to your top-level build.gradle file.
buildscript {
    //...
    repositories {
        //...
        jcenter()
    }
    //...
}
  1. Add the library dependency to your module-level build.gradle file.

Latest version:

ext {
    //...
    adapsterLibraryVersion = "1.0.1"
}

dependencies {
    //...
    implementation "com.arthurivanets.adapster:adapster:$adapsterLibraryVersion"
}
  1. Enable the jetifier and androidX support in the top-level gradle.properties file.
//...
android.enableJetifier=true
android.useAndroidX=true
//....
  1. Update your compileSdkVersion in the module-level build.gradle file to 28+.
//...
android {
    //...
    compileSdkVersion 28
    //...
}
//...
  1. Update your com.android.support.appcompat.* dependency to the new androidx.appcompat.* alternative.
//...
dependencies {
    //...
    implementation "androidx.appcompat:appcompat:1.0.0-beta01"
    //...
}
//...
  1. Proceed with the implementation of your own adapter.

See: Basic RecyclerView-based Implementation and Basic ListView-based Implementation

Basic RecyclerView-based Implementation

Implementation of a basic RecyclerView-based concept involves 3 main steps - creation of concrete Item classes, creation of the adapter, and binding of the adapter to the RecyclerView.

Let's implement a basic RecyclerView-based concept by following the steps listed above:

  1. Creation of a concrete Item class that extends the BaseItem<IM, VH, IR> base class.
  • Creating a model class Article
Kotlin (click to expand)

data class Article(val id : Int,
                   val title : String,
                   val text : String,
                   val imageUrl : String = "") {

    val hasImage : Boolean
        get() = !imageUrl.isBlank()

}

Java (click to expand)

public final class Article {

 private int id;
 private String title;
 private String text;
 private String imageUrl;

 public Article() {
  this.id = -1;
  this.title = "";
  this.text = "";
  this.imageUrl = "";
 }

 // Setters and Getters...

 public final boolean hasImage() {
  return !TextUtils.isEmpty(this.imageUrl);
 }

}

  • Creating the
    ArticleItem item class for the Article modelKotlin (click to expand)

    classArticleItem(itemModel: Article) :BaseItem<Article, ArticleItem.ViewHolder, ItemResources>(itemModel), Trackable<Int> {
    
        overridefuninit(adapter: Adapter<out Item<out RecyclerView.ViewHolder, out ItemResources>>,
                          parent: ViewGroup,
                          inflater: LayoutInflater,
                          resources: ItemResources?) : ViewHolder {
              // inflate (or create) your item view here and create a corresponding ViewHolder// then return the created ViewHolder
        }
    
        overridefunbind(adapter: Adapter<out Item<out RecyclerView.ViewHolder, out ItemResources>>,
                          viewHolder: ViewHolder,
                          resources: ItemResources?) {
            super.bind(adapter, viewHolder, resources)
    
            // bind the data here// (use the itemModel associated with this item to access the data)
        }
    
        overridefungetLayout() :Int {
            // return a unique id, which will be used as a View Type for this item// (you can use the item view layout id if this item's view is not going// to be modified dynamically by adding new views to it, otherwise you will// have to compose your own id to properly distinguish the item's view within your adapter)returnMAIN_LAYOUT_ID
        }
    
        overridefungetTrackKey() :Int {
            // use the model's unique id to prevent the duplicates within the Adapter// (this step is optional and is enabled by the implementation of the Trackable<KeyType> interface)return itemModel.id
        }
    
        classViewHolder(itemView: View) :BaseItem.ViewHolder<Article>(itemView) {
    
            // look up (or initialize) your views here...
    
        }
    
        companion object {
    
            // provide a global unique base id for this item // (it will help you identify the item when assigning the listeners in the adapter)@JvmStaticvalMAIN_LAYOUT_ID:Int= R.layout.article_item_layout
    
        }
    
    }



Java (click to expand)

public final class ArticleItem extends BaseItem<Article, ArticleItem.ViewHolder, ItemResources> implements Trackable<Integer> {

    // provide a global unique base id for this item 
    // (it will help you identify the item when assigning the listeners in the adapter)
    public static final int MAIN_LAYOUT_ID = R.layout.article_item_layout;

    public ArticleItem(Article itemModel) {
        super(itemModel);
    }

    @Override
    public ViewHolder init(Adapter<? extends Item> adapter,
                           ViewGroup parent,
                           LayoutInflater inflater,
                           ItemResources resources) {
          // inflate (or create) your item view here and create a corresponding ViewHolder
          // then return the created ViewHolder
    }

    @Override
    public void bind(Adapter<? extends Item> adapter,
                     ViewHolder viewHolder,
                     ItemResources resources) {
        super.bind(adapter, viewHolder, resources);

        // bind the data here
        // (use the itemModel associated with this item to access the data)
    }
    
    @Override
    public int getLayout() {
        // return a unique id, which will be used as a View Type for this item
        // (you can use the item view layout id if this item's view is not going
        // to be modified dynamically by adding new views to it, otherwise you will
        // have to compose your own id to properly distinguish the item's view within your adapter)
        return MAIN_LAYOUT_ID;
    }

    @Override
    public int getTrackKey() {
        // use the model's unique id to prevent the duplicates within the Adapter
        // (this step is optional and is enabled by the implementation of the Trackable<KeyType> interface)
        return getItemModel().getId();
    }

    public static class ViewHolder extends BaseItem.ViewHolder<Article> {

     public ViewHolder(View itemView) {
      super(itemView);

      // look up (or initialize) your views here...
     }

    }

}

  1. Creation of the adapter that extends the
    TrackableRecyclerViewAdapter<KT, IT, VH> base class.Creating the ArticlesRecyclerViewAdapterKotlin (click to expand)

    classArticlesRecyclerViewAdapter(context: Context, items: MutableList<ArticleItem>) :TrackableRecyclerViewAdapter<Long, ArticleItem, ArticleItem.ViewHolder>(context, items) { varonArticleItemClickListener: OnItemClickListener<ArticleItem>? =null init { setHasStableIds(true) } overridefunassignListeners(holder: ArticleItem.ViewHolder, position:Int, item: ArticleItem) { super.assignListeners(holder, position, item) item.setOnItemClickListener(holder, onArticleItemClickListener) } }

    Java (click to expand)

    publicfinalclassArticlesRecyclerViewAdapterextendsTrackableRecyclerViewAdapter<Long, ArticleItem, ArticleItem.ViewHolder> { privateOnItemClickListener<ArticleItem> onArticleItemClickListener; publicArticlesRecyclerViewAdapter(Contextcontext, List<ArticleItem>items) { super(context, items); setHasStableIds(true); } @OverridepublicvoidassignListeners(ArticleItem.ViewHolderholder, intposition, ArticleItemitem) { super.assignListeners(holder, position, item); item.setOnItemClickListener(holder, onArticleItemClickListener); } publicfinalvoidsetOnItemClickListener(OnItemClickListener<ArticleItem>onArticleItemClickListener) { this.onArticleItemClickListener = onArticleItemClickListener; } }

    1. Instantiation of the created adapter and its binding to the RecyclerView.
      • Instantiating the
        ArticlesRecyclerViewAdapter, setting the Adapter-specific listeners, and binding the adapter to the RecyclerViewKotlin (click to expand)

        //...privatevaritems= ArrayList<ArticleItem>() private lateinit varadapter: ArticlesRecyclerViewAdapter //...privatefuninitRecyclerView() { //... adapter = ArticlesRecyclerViewAdapter(this, items) adapter.onArticleItemClickListener = OnItemClickListener { view, item, position ->// handle the article item click } //... recyclerView.adapter = adapter } //...

        Java (click to expand)

        //...privateList<ArticleItem> items =newArrayList<>();
        privateRecyclerView recyclerView;
        privateArticlesRecyclerViewAdapter adapter;
        
        //...privatevoid initRecyclerView() {
            //....
            recyclerView = findViewById(R.id.recyclerView);
        
            //...
            adapter =newArticlesRecyclerViewAdapter(this, items);
            adpater.setOnArticleItemClickListener(newOnItemClickListener() {
                @OverridepublicvoidonItemClicked(Viewview, ArticleItemitem, intposition) {
                    // handle the article item click
                }
            });
        
            //...
            recyclerView.setAdapter(adapter);
        }