Rx based RecyclerView Adapter

Overview

RxRecyclerAdapter

Release GitHub license Android Arsenal

Rx based generic RecyclerView Adapter Library.

How to use it?

Example!

  • Enable Databinding by adding these lines to your build.gradle
dataBinding {
      enabled = true
}
  • Create the layout file
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="@dimen/activity_horizontal_margin">

        <TextView android:id="@+id/textViewItem"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  tools:text="Recycler Item"/>

    </LinearLayout>
</layout>
  • Create your dataSet
//Dummy DataSet
val dataSet = mutableListOf<String>()
dataSet.add("Lorem")
dataSet.add("ipsum")
dataSet.add("dolor")
dataSet.add("sit")
dataSet.add("amet")
  • Create RxDataSource
// Simple data source
val rxDataSource = RxDataSource<ItemLayoutBinding, String>(R.layout.item_layout, dataSet)

rxDataSource
        .map { it.toUpperCase() }
        .repeat(4)
        .asObservable()
        .subscribe {
            val binding = it.viewDataBinding ?: return@subscribe
            binding.textViewItem.text = it.item
        }

And that's it! The recyclerView is going to show

Changing the data dynamically

Simply call updateAdapter after making changes to the dataSet and that'll do the trick!

rxDataSource.map(...).filter(...).take(...).updateAdapter();

Adapter for multiple View Types

If multiple view types are required for your recyclerView, let's say, we have two types HEADER and ITEM then the coding steps will be :-

  • Enable Databinding
  • Create a list of ViewHolderInfo
//ViewHolderInfo List
val viewHolderInfoList = ArrayList<ViewHolderInfo>()
viewHolderInfoList.add(ViewHolderInfo(R.layout.item_layout, TYPE_ITEM))
viewHolderInfoList.add(ViewHolderInfo(R.layout.item_header_layout, TYPE_HEADER))
  • Create an instance of RxDataSourceSectioned implementation
 // Sectioned data source
val rxDataSourceSectioned = RxDataSourceSectioned(dataSet, viewHolderInfoList, object : OnGetItemViewType() {
    override fun getItemViewType(position: Int): Int {
        if (position % 2 == 0) { // even are headers
            return TYPE_HEADER
        }
        return TYPE_ITEM
    }
})
  • Compose and call bindRecyclerView passing in recyclerView, viewHolderInfoList and viewTypeCallBack
rxDataSourceSectioned
    .asObservable()
    .subscribe {
        val viewDataBinding = it.viewDataBinding
        val data = it.item

        when (viewDataBinding) {
            is ItemLayoutBinding -> viewDataBinding.textViewItem.text = "ITEM: " + data
            is ItemHeaderLayoutBinding -> viewDataBinding.textViewHeader.text = "HEADER: " + data
        }
    }

And the output would look something like

More examples and details here

How to update adapter?

You can update all the data set by call updateDataSet(), then call updateUdapter() to update the adapter (get "notifiyDataSetChange()" effect)

rxDataSource.updateDataSet(newDataSet)
rxDataSource.updateAdapter()

If you want to update one item of the data set, you can use updateDataSet(updatedList, effectedPosition, transactionType),

rxDataSource.updateDataSet(
  dataSet.apply { removeAt(deletedPosition) },
  deletedPosition,
  RxDataSource.TransactionTypes.DELETE
)

Download

Repository available on jCenter

implementation 'com.minimize.android:rxrecycler-adapter:1.3.2'

If the dependency fails to resolve, add this to your project repositories

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

License

Copyright 2015 Ahmed Rizwan

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Feature/adapter changes

    Feature/adapter changes

    Give users the ability to add, delete, modify and replace one item without rerendering all items, and give the user a better feeling by giving the recycler view the ability to animate changes.

    opened by mazenrashed 7
  • Specify License

    Specify License

    I've used this in personal projects and it's pretty good: kudos to you for making it.

    I now want to use this library in some commercial projects. However, without an explicit license I won't be able to due to my client's policies. Would you kindly mention the license by adding it on the root directory of this project?

    opened by mohsin 1
  • Only showing one element

    Only showing one element

    I'm trying to use the lib and my list view is only displaying the first element.

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.simple_recyclerview);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    
    RxDataSource<SimpleViewModel> rxDataSource = new RxDataSource<>(generateSimpleList());
    
    rxDataSource
    	.<MyLayoutBinding>bindRecyclerView(recyclerView, R.layout.my_layout)
    	.subscribe(viewHolder -> {
    		MyLayoutBinding b = viewHolder.getViewDataBinding();
    		SimpleViewModel x = viewHolder.getItem();
    		b.simpleTextView.setText(x);
    	});
    

    The list is of 100 elements

    	private List<SimpleViewModel> generateSimpleList() {
    		List<SimpleViewModel> simpleViewModelList = new ArrayList<>();
    
    		for (int i = 0; i < 100; i++) {
    			simpleViewModelList.add(new SimpleViewModel(String.format(Locale.US, "This is item %d", i)));
    		}
    
    		return simpleViewModelList;
    	}
    

    SimpleViewModel

    public class SimpleViewModel {
    	private String simpleText;
    
    	public SimpleViewModel(@NonNull final String simpleText) {
    		Check.requireNonNull(simpleText);
    		setSimpleText(simpleText);
    	}
    
    	@NonNull
    	public String getSimpleText() {
    		return simpleText;
    	}
    
    	public void setSimpleText(@NonNull final String simpleText) {
    		Check.requireNonNull(simpleText);
    		this.simpleText = simpleText;
    	}
    }
    
    opened by dagostinelli 1
  • Simpler approach?

    Simpler approach?

    Hi @ahmedrizwan,

    I'm relatively new to RxJava and also not an Android expert, so take this proposal with a grain of salt. I have a use-case where not all items of the RecyclerView are known in advance (Bluetooth devices that are discovered dynamically). AFAIS, this use case is not currently covered by RxRecyclerAdapter because all classes basically take a List<T> in advance and allow a certain set of operations on this list.

    Now I was wondering why the classes in the library don't just accept a Observable<List<T>>. Then you wouldn't have to reimplement all those methods in RxDataSource because you could just pass an Observable which has all those operations applied already.

    I've drafted a minimal working example here. Do you see any problems with that approach? Would this be worthy a direction to pursue in RxRecyclerAdapter, or should I rather create this as a separate project?

    opened by nightscape 1
  •  How to set Adapter onItemClick  event it please?

    How to set Adapter onItemClick event it please?

    I follow you.And thanks a lot. You open my eyes. but how to set Adapter onItemClick event it ?please 。 like this? rxDataSource.repeat(1). bindRecyclerView(fragmentBinding.mGridView, R.layout.item_homepage_gridview) .subscribe(viewHolder -> { RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(ViewGroup .LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); ItemHomepageGridviewBinding dataBinding = viewHolder.getViewDataBinding(); param.width=screenWidth/3; param.height = screenWidth/5; dataBinding.gridviewRoot.setLayoutParams(param); long itemId = viewHolder.getItemId(); String item = viewHolder.getItem(); if(itemId < lastCount){ Picasso.with(getActivity()).load(item).into(dataBinding.gridviewNetImage); }else{ dataBinding.gridviewNetImage.setImageResource(R.drawable.gridview_background); } dataBinding.getRoot().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {

                        }
                    });
                });
    
    opened by CodeK1988 1
  • Fix broken headings in Markdown files

    Fix broken headings in Markdown files

    GitHub changed the way Markdown headings are parsed, so this change fixes it.

    See bryant1410/readmesfix for more information.

    Tackles bryant1410/readmesfix#1

    opened by bryant1410 0
  • [Question] How to pass an Rx obserable as the dataset instead?

    [Question] How to pass an Rx obserable as the dataset instead?

    I'm trying to combine this with RxPreferences. I have a List stored as shared preferences and every time this pref object gets updated I want the recycler view (using this library) to be updated as well. Think of Whatsapp chats example where when a new message comes it updated the list but all data it stored internally (shared prefs in this example).

    I'm currently using this code to solve my problem (which kinda works perfectly):

    val chatsPref = rxSharedPreferences.getObject("chats", emptyList(), ChatsPreferenceAdapter(gson))
    val chats = chatsPref.get()
    val rxDataSource = RxDataSource<ChatItemBinding, Chat>(R.layout.chat_item, chats)
    disposables.add(
        rxDataSource.asObservable()
            .subscribe {
                val item = it.item!!
                val binding = it.viewDataBinding!!
    
                binding.tvMessage.text = item.message
            }
    )
    
    disposables.add(chatsPref.asObservable()
        .subscribe {
            rxDataSource.updateDataSet(it).updateAdapter()
        }
    )
    

    You can see that in this, I'm first extracting the initial value of chats using chatsPref.get() and then initializing my RxDataSource object using that and then in the last few lines, using the observable stream of the preference item to let the data source update. Is there a way I can cut down the lines to directly pass chatsPref.asObservable() into RxDataSource during initialization to avoid all these extra steps?

    opened by mohsin 0
  • Use a Consumer instead of the event to get even closer to the Rx paradigm

    Use a Consumer instead of the event to get even closer to the Rx paradigm

    While looking at this example (Line 58), I thought a Consumer would be a better fit than using an override to react to an event. It would make this lib even more Rx!

    Anyhow, I like this lib so far. I just think it deserves more documentation. Keep up the good work!

    opened by Vrakfall 0
  • Viewholder Data binding and click listener

    Viewholder Data binding and click listener

    Sorry to ask, But I do have 2 question with RxReyclerAdapter,

    1. How can we specific set data for many view in the viewholder, Ex. We have 1 ImageView, and Title, And Description.Support we use List, that contain 3 attribute for the list,
    2. How to set event click for each row of the item in the viewholder, to get the index of position.
    opened by TuonBondol 0
  • Use inside a fragment?

    Use inside a fragment?

    Hi, i have this code on my fragment:

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            fragmentHomeBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.fragment_home, container, false);
            fragmentHomeBinding.rv.setLayoutManager(new LinearLayoutManager(getContext()));
            fragmentHomeBinding.rv.setHasFixedSize(true);
            //Dummy DataSet
            mCompositeSubscription.add(HaipService.getMyPendingCampaigns()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .flatMap(campaigns -> {
                        pending = new RxDataSource<>(campaigns);
                        return pending.<MainItemBinding>bindRecyclerView(fragmentHomeBinding.rv, R.layout.main_item);
                    })
                    .doOnNext(campaignMainItemBindingSimpleViewHolder -> {
                        fragmentHomeBinding.rv.setAdapter(pending.getRxAdapter());
                    })
                    .subscribe(viewHolder -> {
                        MainItemBinding item = viewHolder.getViewDataBinding();
                        Campaign campaign = viewHolder.getItem();
                        Log.d("I'm here", campaign.getName());
    
                        Picasso.with(getContext()).load(campaign.getLogo()).fit().centerInside().into(item.brandImage);
                        Picasso.with(getContext()).load(campaign.getImage())
                                .fit().centerCrop().into(item.campaignImage);
                        item.brandName.setText(campaign.getName());
                        item.progressBar.setProgress(campaign.getCompleteStatus());
                        item.completedPercent.setText(String.valueOf(campaign.getCompleteStatus()) + "%");
                    }, Throwable::printStackTrace));
            return fragmentHomeBinding.getRoot();
    
        }
    

    but when I run the app, i'm only get

    E/RecyclerView: No adapter attached; skipping layout

    If I test the same code on an Activity, it works (changing DataBindingUtil.inflate by DataBindingUtil.setContentView).

    Is this the correct way to bind a recyclerView inside a fragment?

    opened by jaambee 3
Releases(1.2.1)
  • 1.2.1(Dec 27, 2015)

  • 1.0.1(Dec 14, 2015)

    Added method setOnViewHolderInflated for RxAdapter and RxAdapterForTypes For example, if you want to change the height of an item dynamically based on viewType - code will be

    rxAdapterForTypes.setOnViewHolderInflate(new OnViewHolderInflated() {
                @Override
                public void onInflated(final View view, final ViewGroup parent, final int viewType) {
                    if(viewType==1){
                        view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                parent.getMeasuredHeight()));
                    }
                }
    });
    
    Source code(tar.gz)
    Source code(zip)
Owner
Ahmed Rizwan
React | Android | RN
Ahmed Rizwan
Create a new adapter for a RecyclerView or ViewPager is now much easier.

Efficient Adapter for Android Create a new adapter for a RecyclerView or ViewPager is now much easier. Overview Create a list of elements into a Recyc

Stan Kocken 423 Sep 16, 2022
This Repository simplifies working with RecyclerView Adapter

AutoAdapter This Repository simplifies working with RecyclerView Adapter Gradle: Add it in your root build.gradle at the end of repositories: allproj

George Dzotsenidze 151 Aug 15, 2021
Generic RecyclerView adapter

Generic RecyclerView Adapter. Lightweight library which simplifies creating RecyclerView adapters and illuminates writing boilerplate code. Creating a

Leonid Ustenko 77 Dec 24, 2022
Android library for the adapter view (RecyclerView, ViewPager, ViewPager2)

Antonio Android library for the adapter view (RecyclerView, ViewPager, ViewPager2) Free from implementation of the adapter's boilerplate code ! Reuse

NAVER Z 106 Dec 23, 2022
The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction...

FastAdapter The FastAdapter is here to simplify creating adapters for RecyclerViews. Don't worry about the adapter anymore. Just write the logic for h

Mike Penz 3.7k Jan 8, 2023
Android - A ListView adapter with support for multiple choice modal selection

MultiChoiceAdapter MultiChoiceAdapter is an implementation of ListAdapter which adds support for modal multiple choice selection as in the native Gmai

Manuel Peinado Gallego 855 Nov 11, 2022
A slim & clean & typeable Adapter without# VIEWHOLDER

PLEASE NOTE, THIS PROJECT IS NO LONGER BEING MAINTAINED First At A Glance :) Intro A slim & clean & typeable Adapter without# VIEWHOLDER Features No V

lin 940 Dec 30, 2022
Adapter Kit is a set of useful adapters for Android.

Adapter Kit Adapter Kit is a set of useful adapters for Android. The kit currently includes, Instant Adapter Instant Cursor Adapter Simple Section Ada

Ragunath Jawahar 368 Nov 25, 2022
Simplify Adapter creation for your Android ListViews.

FunDapter takes the pain and hassle out of creating a new Adapter class for each ListView you have in your Android app. It is a new approach to custom

Ami Goldenberg 287 Dec 22, 2022
Small, smart and generic adapter for recycler view with easy and advanced data to ViewHolder binding.

smart-recycler-adapter Never code any boilerplate RecyclerAdapter again! This library will make it easy and painless to map your data item with a targ

Manne Öhlund 405 Dec 30, 2022
Epoxy is an Android library for building complex screens in a RecyclerView

Epoxy Epoxy is an Android library for building complex screens in a RecyclerView. Models are automatically generated from custom views or databinding

Airbnb 8.1k Jan 4, 2023
Renderers is an Android library created to avoid all the boilerplate needed to use a RecyclerView/ListView with adapters.

Renderers Renderers is an Android library created to avoid all the RecyclerView/Adapter boilerplate needed to create a list/grid of data in your app a

Pedro Vicente Gómez Sánchez 1.2k Nov 19, 2022
Android library to auto-play/pause videos from url in recyclerview.

AutoplayVideos Show some ❤️ and star the repo to support the project This library is created with the purpose to implement recyclerview with videos ea

Krupen Ghetiya 989 Nov 17, 2022
:page_with_curl: [Android Library] Giving powers to RecyclerView

Android library that provides most common functions around recycler-view like Swipe to dismiss, Drag and Drop, Divider in the ui, events for when item

Nishant Srivastava 644 Nov 20, 2022
Rx based RecyclerView Adapter

RxRecyclerAdapter Rx based generic RecyclerView Adapter Library. How to use it? Example! Enable Databinding by adding these lines to your build.gradle

Ahmed Rizwan 193 Jun 18, 2022
Elegant design and convenient to use RecyclerView adapter library based on Kotlin DSL.

xAdapter: Kotlin DSL 风格的 Adapter 封装 1、简介 该项目是 KotlinDSL 风格的 Adapter 框架封装,用来简化 Adapter 调用,思想是采用工厂和构建者方式获取 Adapter 避免代码中定义大量的 Adapter 类。该项目在 BRVAH 的 Ada

ShouHeng 17 Oct 9, 2022
An adapter which could be used to achieve a parallax effect on RecyclerView.

android-parallax-recycleview Integration Step 1. Add the JitPack repository to your build file repositories { maven { url "https://jitpack

Pedro Oliveira 1.6k Nov 17, 2022
Android library defining adapter classes of RecyclerView to manage multiple view types

RecyclerView-MultipleViewTypeAdapter RecyclerView adapter classes for managing multiple view types Release Note [Release Note] (https://github.com/yqr

Yoshihito Ikeda 414 Nov 21, 2022
An Adapter that allows a RecyclerView to be split into Sections with headers and/or footers. Each Section can have its state controlled individually.

⚠️ Archived: this repository is no longer going to be maintained. SectionedRecyclerViewAdapter An Adapter that allows a RecyclerView to be split into

Gustavo Pagani 1.7k Dec 21, 2022
Create a new adapter for a RecyclerView or ViewPager is now much easier.

Efficient Adapter for Android Create a new adapter for a RecyclerView or ViewPager is now much easier. Overview Create a list of elements into a Recyc

Stan Kocken 423 Sep 16, 2022