The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction...

Overview

FastAdapter

The FastAdapter is here to simplify creating adapters for RecyclerViews. Don't worry about the adapter anymore. Just write the logic for how your view/item should look like, and you are done. It's blazing fast, minimizing the code you need to write, and is easy to extend.


What's included 🚀 Setup 🛠️ Migration Guide 🧬 Used bySample App


What's included 🚀

Preview

Screenshots 🎉

Image

Setup

Latest releases 🛠

Provide the gradle dependency

The library is split up into core, commons, and extensions. The core functions are included in the following dependency.

implementation "com.mikepenz:fastadapter:${latestFastAdapterRelease}"
implementation "androidx.appcompat:appcompat:${androidX}"
implementation "androidx.recyclerview:recyclerview:${androidX}"

Expandable support is included and can be added via this

implementation "com.mikepenz:fastadapter-extensions-expandable:${latestFastAdapterRelease}"

Many helper classes are included in the following dependency.

implementation "com.mikepenz:fastadapter-extensions-binding:${latestFastAdapterRelease}" // view binding helpers
implementation "com.mikepenz:fastadapter-extensions-diff:${latestFastAdapterRelease}" // diff util helpers
implementation "com.mikepenz:fastadapter-extensions-drag:${latestFastAdapterRelease}" // drag support
implementation "com.mikepenz:fastadapter-extensions-paged:${latestFastAdapterRelease}" // paging support
implementation "com.mikepenz:fastadapter-extensions-scroll:${latestFastAdapterRelease}" // scroll helpers
implementation "com.mikepenz:fastadapter-extensions-swipe:${latestFastAdapterRelease}" // swipe support
implementation "com.mikepenz:fastadapter-extensions-ui:${latestFastAdapterRelease}" // pre-defined ui components
implementation "com.mikepenz:fastadapter-extensions-utils:${latestFastAdapterRelease}" // needs the `expandable`, `drag` and `scroll` extension.

// required for the ui components and the utils
implementation "com.google.android.material:material:${androidX}"

How to use

1. Implement your item

1a. Implement your item as usual (the easy way)

Just create a class which extends the AbstractItem as shown below. Implement the methods, and your item is ready.

open class SimpleItem : AbstractItem<SimpleItem.ViewHolder>() {
    var name: String? = null
    var description: String? = null

    /** defines the type defining this item. must be unique. preferably an id */
    override val type: Int
        get() = R.id.fastadapter_sample_item_id

    /** defines the layout which will be used for this item in the list */
    override val layoutRes: Int
        get() = R.layout.sample_item

    override fun getViewHolder(v: View): ViewHolder {
        return ViewHolder(v)
    }

    class ViewHolder(view: View) : FastAdapter.ViewHolder<SimpleItem>(view) {
        var name: TextView = view.findViewById(R.id.material_drawer_name)
        var description: TextView = view.findViewById(R.id.material_drawer_description)

        override fun bindView(item: SimpleItem, payloads: List<Any>) {
            name.text = item.name
            description.text = item.name
        }

        override fun unbindView(item: SimpleItem) {
            name.text = null
            description.text = null
        }
    }
}

1b. Implement item with ViewBinding (the easiest way)

class BindingIconItem : AbstractBindingItem<IconItemBinding>() {
    var name: String? = null

    override val type: Int
        get() = R.id.fastadapter_icon_item_id

    override fun bindView(binding: IconItemBinding, payloads: List<Any>) {
        binding.name.text = name
    }

    override fun createBinding(inflater: LayoutInflater, parent: ViewGroup?): IconItemBinding {
        return IconItemBinding.inflate(inflater, parent, false)
    }
}

Use the binding extension dependency in your application for this.

2. Set the Adapter to the RecyclerView

//create the ItemAdapter holding your Items
val itemAdapter = ItemAdapter<SimpleItem>()
//create the managing FastAdapter, by passing in the itemAdapter
val fastAdapter = FastAdapter.with(itemAdapter)

//set our adapters to the RecyclerView
recyclerView.setAdapter(fastAdapter)

//set the items to your ItemAdapter
itemAdapter.add(ITEMS)

3. Extensions

By default the FastAdapter only provides basic functionality, which comes with the abstraction of items as Item and Model. And the general functionality of adding/removing/modifying elements. To enable selections, or expandables the provided extensions need to be activated.

3.1. SelectExtension

// Gets (or creates and attaches if not yet existing) the extension from the given `FastAdapter`
val selectExtension = fastAdapter.getSelectExtension()
// configure as needed
selectExtension.isSelectable = true
selectExtension.multiSelect = true
selectExtension.selectOnLongClick = false
// see the API of this class for more options.

3.2. ExpandableExtension

This requires the fastadapter-extensions-expandable extension.

// Gets (or creates and attaches if not yet existing) the extension.
val expandableExtension = fastAdapter.getExpandableExtension()
// configure as needed
expandableExtension.isOnlyOneExpandedItem = true

For further details scroll down to the ExpandableItems (under advanced usage) section.

3. Click listener

fastAdapter.onClickListener = { view, adapter, item, position ->
    // Handle click here
    false
}

4. Click listeners for views inside your item

// just add an `EventHook` to your `FastAdapter` by implementing either a `ClickEventHook`, `LongClickEventHook`, `TouchEventHook`, `CustomEventHook`
fastAdapter.addEventHook(object : ClickEventHook<SimpleImageItem>() {
    override fun onBind(viewHolder: RecyclerView.ViewHolder): View? {
        //return the views on which you want to bind this event
        return if (viewHolder is SimpleImageItem.ViewHolder) {
            viewHolder.viewWhichReactsOnClick
        } else {
	    null
	}
    }

    override fun onClick(v: View, position: Int, fastAdapter: FastAdapter<SimpleImageItem>, item: SimpleImageItem) {
        //react on the click event
    }
})

5. Filter

// Call this in onQueryTextSubmit() & onQueryTextChange() when using SearchView
itemAdapter.filter("yourSearchTerm")
itemAdapter.itemFilter.filterPredicate = { item: SimpleItem, constraint: CharSequence? ->
    item.name?.text.toString().contains(constraint.toString(), ignoreCase = true)
}

filter() should return true for items to be retained and false for items to be removed.

6. Drag and drop

This requires the fastadapter-extensions-drag extension.

First, attach ItemTouchHelper to RecyclerView.

val dragCallback = SimpleDragCallback()
val touchHelper = ItemTouchHelper(dragCallback)
touchHelper.attachToRecyclerView(recyclerView)

Implement ItemTouchCallback interface in your Activity, and override the itemTouchOnMove() method.

override fun itemTouchOnMove(oldPosition: Int, newPosition: Int): Boolean {
    DragDropUtil.onMove(fastItemAdapter.itemAdapter, oldPosition, newPosition) // change position
    return true
}

7. Using different ViewHolders (like HeaderView)

Start by initializing your adapters:

// Header is a model class for your header
val headerAdapter = ItemAdapter<Header>()

Initialize a Model FastAdapter:

val itemAdapter = GenericItemAdapter()

Finally, set the adapter:

val fastAdapter: GenericFastAdapter = FastAdapter.with(headerAdapter, itemAdapter) //the order defines in which order the items will show up
// alternative the super type of both item adapters can be used. e.g.:
recyclerView.setAdapter(fastAdapter)

8. Infinite (endless) scrolling

Create a FooterAdapter. We need this to display a loading ProgressBar at the end of our list. (Don't forget to pass it into FastAdapter.with(..))

val footerAdapter = ItemAdapter<ProgressItem>()

Keep in mind that ProgressItem is provided by FastAdapter’s extensions.

recyclerView.addOnScrollListener(object : EndlessRecyclerOnScrollListener(footerAdapter) {
     override fun onLoadMore(currentPage: Int) {
         footerAdapter.clear()
         footerAdapter.add(ProgressItem())
         
	 // Load your items here and add it to FastAdapter
         itemAdapter.add(NEWITEMS)
    }
})

For the complete tutorial and more features such as multi-select and CAB check out the sample app.

Advanced Usage

Proguard

  • As of v2.5.0 there are no more known requirements to use the FastAdapter with Proguard

ExpandableItems

The FastAdapter comes with support for expandable items. After adding the dependency set up the Expandable extension via:

val expandableExtension = fastAdapter.getExpandableExtension()

Expandable items have to implement the IExpandable interface, and the sub items the ISubItem interface. This allows better support. The sample app provides sample implementations of those. (Those in the sample are kept Model which allows them to be used with different parent / subitems)

As of the way how SubItems and their state are handled it is highly recommended to use the identifier based StateManagement. Just add withPositionBasedStateManagement(false) to your FastAdapter setup.

A simple item just needs to extend from the AbstractExpandableItem and provide the ViewHolder as type.

open class SimpleSubExpandableItem : AbstractExpandableItem<SimpleSubExpandableItem.ViewHolder>() {

    /**
     * BASIC ITEM IMPLEMENTATION
     */
}

// See the SimpleSubExpandableItem.kt of the sample application for more details.

Articles

Used by

Mike Penz:

Developed By

Contributors

This free, open source software was also made possible by a group of volunteers that put many hours of hard work into it. See the CONTRIBUTORS.md file for details.

Special mentions

A special thanks to the very active contributors who added many improvements to this library.

License

Copyright 2021 Mike Penz

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
  • Multiselect + Subitems + Deletion problem

    Multiselect + Subitems + Deletion problem

    Based on your multi select and expandable list example, I'm trying to combine those two - I think I did not change anything relevant.

    Showing the data with headers works fine, expanding/collapsing works fine. BUT as soon as I start deleting something, it get's messed up.

    Observations

    • deleting items and not collapsing anything works visually fine

    Problem

    • I select the first sub item and delete it, then I collapse the first header and see, the second one is missing
    • I select the first two sub items and delete them, then I collapse the first header and see, the second and third header is missing

    Afterwards, more problems occur (expanding a header that still exists will show selected items for example, ...)

    How I set up my adapter

        mFastAdapter = new FastItemAdapter<>();
        mActionModeHelper = new ActionModeHelper(mFastAdapter, R.menu.menu_folders, new ActionBarCallBack());
    
        // 2) FastAdapter Setup
        mFastAdapter.withSelectable(true);
        mFastAdapter.withMultiSelect(true);
        mFastAdapter.withSelectOnLongClick(true);
        mFastAdapter.withOnPreClickListener(new FastAdapter.OnClickListener<IItem>() {
            @Override
            public boolean onClick(View v, IAdapter<IItem> adapter, IItem item, int position) {
                //we handle the default onClick behavior for the actionMode. This will return null if it didn't do anything and you can handle a normal onClick
                Boolean res = mActionModeHelper.onClick(item);
                return res != null ? res : false;
            }
        });
        mFastAdapter.withOnPreLongClickListener(new FastAdapter.OnLongClickListener<IItem>() {
            @Override
            public boolean onLongClick(View v, IAdapter<IItem> adapter, IItem item, int position) {
                ActionMode actionMode = mActionModeHelper.onLongClick(mActivity, position);
    
                if (actionMode != null) {
                    //we want color our CAB
                    mActivity.findViewById(R.id.action_mode_bar).setBackgroundColor(UIUtils.getThemeColorFromAttrOrRes(mActivity, R.attr.colorPrimary, R.color.material_drawer_primary));
                }
    
                //if we have no actionMode we do not consume the event
                return actionMode != null;
            }
        });
    

    How I fill my data

        // List of sub items without headers
        List<FolderItem> folders = ...;
    
        // Test - group items in groups of 10
        List<IItem> items = new ArrayList<>();
        int count = folders.size();
        int headers = (int)Math.ceil((float)folders.size() / 10f);
        for (int i = 0; i < headers; i++)
        {
            FolderItemHeader header = new FolderItemHeader()
                    .withHeader("Header " + (i + 1))
                    .withName("Header " + (i + 1))
                    .withDescription("Description...")
                    .withSubItems(folders.subList(i * 10, Math.min(count, i * 10 + 10)))
                    // ALL folder items have an id that represents the rowid in the database, so
                    // the ids are > 0 AND unique for sure!
                    // using ids < 0 will result in no confilcting ids for sure
                    .withIdentifier(-1 - i)
                    .withIsExpanded(true);
            items.add(header);
        }
    
        // set data
        FastItemAdapter<IItem> fastAdapter = (FastItemAdapter<IItem>)mBinding.rvData.getAdapter();
        fastAdapter.setNewList(items);
    
    bug enhancement 
    opened by MFlisar 50
  • [V3][V3][V3] TEST, API, SUGGESTIONS

    [V3][V3][V3] TEST, API, SUGGESTIONS

    We are currently in the progress of finalising the API changes and a huge refactor for the FastAdapter.

    As it is really important for us to make the library as easy to use, but also as powerful and flexible as possible, we want to hear your feedback.

    You can follow the current progress here: https://github.com/mikepenz/FastAdapter/pull/443 and also use the SNAPSHOT to include it into your app, and test it out. Currently the only documentation for V3 is the commit changelog + the sample application.

    Please check it out, and give us suggestions, review the changes, and contribute and help to make v3 the best release ever.

    Please keep general discussion here, and do code reviews on the PR.


    OVERVIEW

    • Adapter wrapping was removed
      • FastAdapter.with() is the new way to go
    • HeaderAdapter, FooterAdapter were removed, just use multiple ItemAdapters instead
    • Extension support
      • Selection (currently still in the core lib) and Expandable's are no longer a core functionality, but instead use the Extension interface, to add their functionality to the library
    • GenericItemAdapter's will be removed and replaced in favour of the new ModelAdapter
    • The ItemAdapter is now based on the ModelAdapter (this sadly required a second generic type to be defined)
    • ...
    enhancement help wanted question good to know unrelated 
    opened by mikepenz 39
  • RealmObjects + Grouping / Headers

    RealmObjects + Grouping / Headers

    Hello, I'm using Realm as my local backend and I would like to use the FastAdapter to populate my (many) RecyclerViews, however my realm models are separated from the ui part in its own project and each of the objects could be used on several views, so to extend my models as in the RealmExample is not an option.

    Also I would like to be able to sort my adapters, and group them (providing a group header). I've reading the documentation and the examples and I'm a bit confused about what adapter to use and where, and how to add a "headeritem". The following is what I have made so far:

    I have a Realm class like the following (I will omit the get and sets for the realm part)

    public class Contender extends RealmObject  {
    
        @PrimaryKey
        private String UUID;
        private String name;
        private int total;
        private Competition competition;
    
    }
    

    Where Competition is another RealmObject:

    public class Competition extends RealmObject  {
    
        @PrimaryKey
        private String UUID;
        private String name;
    }
    

    In order to populate a FastAdapter I have created a ContenderItem like this:

    public class ContenderItem  extends GenericAbstractItem<Contender, ContenderItem, ContenderItem.ViewHolder>
    {
    
        //the static ViewHolderFactory which will be used to generate the ViewHolder for this Item
        private static final ViewHolderFactory<? extends ViewHolder> FACTORY = new ItemFactory();
    
        public ContenderItem(Contender contender) {
            super(contender);       
        }
    
        public int getTotal()
        {
            return getModel().getTotal();
        }
    
        public String getTotalString()
        {
            return String.valueOf(getTotal());
        }
    
        public String getCompetitionDescription()
        {
            return getModel().getCompetition().getName();
        }
    
    
        @Override
        public int getType() {
            return R.id.fastadapter_generic_icon_item_id;
        }
    
        @Override
        public int getLayoutRes() {
            return R.layout.list_contender_item;
        }
    
        @Override
        public void bindView(ViewHolder holder) {
            super.bindView(holder);   
            holder.title.setText(getModel().getName());
            holder.subtitle.setText(getCompetitionDescription());
        }
    
        /**
         * our ItemFactory implementation which creates the ViewHolder for our adapter.
         * It is highly recommended to implement a ViewHolderFactory as it is 0-1ms faster for ViewHolder creation,
         * and it is also many many times more efficient if you define custom listeners on views within your item.
         */
        protected static class ItemFactory implements ViewHolderFactory<ViewHolder> {
            public ViewHolder create(View v) {
                return new ViewHolder(v);
            }
        }
    
        /**
         * return our ViewHolderFactory implementation here
         *
         * @return
         */
        @Override
        public ViewHolderFactory<? extends ViewHolder> getFactory() {
            return FACTORY;
        }
    
    
         * A simple Comparator to sort the items ascending.
         */
        public static class TotalComparatorAscending implements Comparator<ContenderItem>, Serializable {
            @Override
            public int compare(ContenderItem lhs, ContenderItem rhs) {
                if (lhs.getCompetitionDescription().equals(rhs.getCompetitionDescription()))
                    return Integer.valueOf(lhs.getTotal()).compareTo(rhs.getTotal());
                return  lhs.getCompetitionDescription().compareTo(rhs.getCompetitionDescription());
            }
        }
    
        /**
         * A simple Comparator to sort the items ascending.
         */
        public static class TotalComparatorDescending implements Comparator<ContenderItem>, Serializable {
            @Override
            public int compare(ContenderItem lhs, ContenderItem rhs) {
                if (lhs.getCompetitionDescription().equals(rhs.getCompetitionDescription()))
                    return -Integer.valueOf(lhs.getTotal()).compareTo(rhs.getTotal());
                return  -lhs.getCompetitionDescription().compareTo(rhs.getCompetitionDescription());
            }
        }
    
    
        /**
         * our ViewHolder
         */
        protected static class ViewHolder extends RecyclerView.ViewHolder {
            protected View view;
    
            @BindView(R.id.title_textview)
            AppCompatTextView title;
    
            @BindView(R.id.subtitle_textview)
            AppCompatTextView subtitle;
    
            public ViewHolder(View view) {
                super(view);
                ButterKnife.bind(this, view);
                this.view = view;
            }
        }
    }
    

    I have a RecyclerView that is populated on the onViewCreated method of the Fragment that holds it:

      private FastAdapter fastAdapter;
     @Override
       public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
                //create our FastAdapter which will manage everything
            fastAdapter = new FastAdapter();
            GenericItemAdapter<Contender, ContenderItem> itemAdapter = new GenericItemAdapter<>(ContenderItem::new);
            RecyclerView.Adapter adapter = itemAdapter.wrap(fastAdapter);
    
           RealmResults<Contender> contenderList = realm.where(Contender.class).findAll();
           itemAdapter.addModel(contenderList);
    
    }
    
    

    This code is working ok and although I'm not so sure about if I should use the GenericItemAdapter or another adapter, it is very straightforward.

    Now I want to group all contenders by competitions, an add add a "Header / section item" with the competition name, and here is where I'm stuck.

    I started by creating a "SectionItem" very similar to the ContenderItem:

    
    public class SectionItem extends AbstractItem<SectionItem, SectionItem.ViewHolder> {
    
    
        //the static ViewHolderFactory which will be used to generate the ViewHolder for this Item
        private static final ViewHolderFactory<? extends ViewHolder> FACTORY = new ItemFactory();
    
        private String title = "";
    
        @Override
        public int getType() {
            return 0;
        }
    
        @Override
        public int getLayoutRes() {
            return R.layout.list_section_header;
        }
    
        public SectionItem withTitle(String title)
        {
            this.title = title;
            return this;
        }
    
        @Override
        public void bindView(ViewHolder holder) {
            super.bindView(holder);
            holder.title.setText(title);
        }
    
        /**
         * our ItemFactory implementation which creates the ViewHolder for our adapter.
         * It is highly recommended to implement a ViewHolderFactory as it is 0-1ms faster for ViewHolder creation,
         * and it is also many many times more efficient if you define custom listeners on views within your item.
         */
        protected static class ItemFactory implements ViewHolderFactory<SectionItem.ViewHolder> {
            public SectionItem.ViewHolder create(View v) {
                return new SectionItem.ViewHolder(v);
            }
        }
    
        /**
         * return our ViewHolderFactory implementation here
         *
         * @return
         */
        @Override
        public ViewHolderFactory<? extends SectionItem.ViewHolder> getFactory() {
            return FACTORY;
        }
    
    
        public static class ViewHolder extends RecyclerView.ViewHolder {
            protected View view;
    
            @BindView(R.id.section_text)
            AppCompatTextView title;
    
            public ViewHolder(View view) {
                super(view);
                ButterKnife.bind(this, view);
                this.view = view;
            }
        }
    }
    
    

    And, using streams is very easy to group the data:

    
            Map<Competition, List<Contender>> contendersGrouped = Stream.of(contenders).collect(Collectors.groupingBy(value -> value.getCompetition()));
    
    

    But I'm stuck here, I don't know If I have to change the itemAdapter so it can use both types of items (ContenderItem and SectionItem), or I can just wrap the itemAdapter in another adapter (A HeaderAdapter), but then I don't know how to link both so they group properly.

    So my questions are the following:

    1. Am I using the best way to link the realm library with FastAdapter without extending the model?
    2. What is the best way to create a grouped by property adapter with section items?

    Thank you for your awesome work,

    Gabriel

    question 
    opened by gpulido 35
  • Setting TouchListener in ViewHolder constructor

    Setting TouchListener in ViewHolder constructor

    I think following SHOULD work, but it does not. Any ideas why?

    public class Item
    {
        @Override
        public void bindView(ViewHolder viewHolder, List payloads)
        {
            super.bindView(viewHolder, payloads);
    
            // place 1: here it works as expected
            ViewUtil.addTouchResize(viewHolder.itemView);
        }
    
        @Override
        public void unbindView(ViewHolder viewHolder)
        {
            super.unbindView(viewHolder);
            viewHolder.reset();
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder
        {
            public ViewHolder(View view)
            {
                super(view);
                // place 2: here it does NOT work
                ViewUtil.addTouchResize(view);
            }
            
            public void reset()
            {
                ViewUtil.clearAnimation(itemView);
            }
        }
    }
    

    My ViewUtil calls view.setOnTouchListener(...) in addTouchResize and restores all views settings and cancels all animations in clearAnimation.

    I should set the onTouchListener only when I create the ViewHolder not everytime it gets bound. Any ideas why this is not working in the ViewHolders constructor?

    question 
    opened by MFlisar 23
  • Method does not override method from its superclass

    Method does not override method from its superclass

    Hi! When I copy and paste SampleItem class Android Studio returns me this error: image I've only changed name of the class.

    package com.franci22.supersecureencryption.items;
    
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.TextView;
    
    import com.franci22.supersecureencryption.R;
    import com.mikepenz.fastadapter.items.AbstractItem;
    
    import java.util.List;
    
    public class ListItem extends AbstractItem<ListItem, ListItem.ViewHolder> {
    
        public String name;
        public String description;
    
        //The unique ID for this type of item
        @Override
        public int getType() {
            return R.id.list_item_id;
        }
    
        //The layout to be used for this type of item
        @Override
        public int getLayoutRes() {
            return R.layout.list_item;
        }
    
        //The logic to bind your data to the view
        @Override
        public void bindView(ViewHolder viewHolder, List<Object> payloads) {
            //call super so the selection is already handled for you
            super.bindView(viewHolder, payloads);
    
            //bind our data
            //set the text for the name
            viewHolder.name.setText(name);
            //set the text for the description or hide
            viewHolder.description.setText(description);
        }
    
        //reset the view here (this is an optional method, but recommended)
        @Override
        public void unbindView(ViewHolder holder) {
            super.unbindView(holder);
            holder.name.setText(null);
            holder.description.setText(null);
        }
    
        //The viewHolder used for this item. This viewHolder is always reused by the RecyclerView so scrolling is blazing fast
        protected static class ViewHolder extends RecyclerView.ViewHolder {
            protected TextView name;
            protected TextView description;
    
            public ViewHolder(View view) {
                super(view);
                this.name = (TextView) view.findViewById(R.id.material_drawer_name);
                this.description = (TextView) view.findViewById(R.id.material_drawer_description);
            }
        }
    }
    

    Why? Thanks!

    question 
    opened by francescotarantino 22
  • NEW StateManagment behavior

    NEW StateManagment behavior

    I am currently trying and testing a NEW behavior of the FastAdapter which will allow more flexibility for developers.

    All changes are done in this branch: https://github.com/mikepenz/FastAdapter/commits/feature/alternativeStateManagement

    And a first demo application is also available: https://drive.google.com/open?id=0B4Y8HN2BnSjpdG04MGk0cnMySmc

    I would be happy If people could test this new behavior and report back.

    You can also test the whole thing in your app via this SNAPSHOT (available on the SNAPSHOT maven repo):

    compile('com.mikepenz:fastadapter:1.5.0.b2-SNAPSHOT@aar') {
        transitive = true
    }
    
    //extension:
    compile 'com.mikepenz:fastadapter-extensions:1.5.0.b2-SNAPSHOT@aar'
    //The tiny Materialize library used for its useful helper classes
    compile 'com.mikepenz:materialize:0.8.8@aar'
    
    enhancement help wanted 
    opened by mikepenz 22
  • possible bug: duplicate images when scrolling

    possible bug: duplicate images when scrolling

    Details

    • [ ] Used library version 3.2.5
    • [ ] Used support library version 27.1.1
    • [ ] Used gradle build tools version 3.1.3
    • [ ] Used tooling / Android Studio version 3.1.3

    About this issue

    i am not sure if this is a bug in the library or somewhere else or if im somehow missing something... the issue is that some views do not seem to be binded/unbinded properly and i am getting duplicate images. here is an example:

    capture _2018-07-18-14-55-45

    as you can see, "Madam Secretary" and "Nashville" have the same image. this seems to be happening at random - if i scroll up and down a few times, this would happen to different items.

    things to note (in case they matter):

    • i am using kotlin
    • i am using ModelAdapter
    • the adapter is filtered while this is happening

    here are my bindView and unbindView:

    override fun bindView(holder: ViewHolder, payloads: MutableList<Any>)
        {
            super.bindView(holder, payloads)
    
            val view = holder.view
            val context = view.context
    
            Picasso.with(context)
                .load(model._imageUrl)
                .placeholder(R.drawable.image_loading)
                .error(R.drawable.image_error)
                .fit()
                .centerInside()
                .into(view.iv_showImage)
    
            (view as FrameLayout).foreground =
                    FastAdapterUIUtils.getSelectablePressedBackground(context,
                                                                      context.resources.getColor(R.color.colorPrimaryTransparent),
                                                                      255,
                                                                      true)
            val nameAndYear = "${model._name}\n(${model._year})"
            view.tv_nameAndYear.text = nameAndYear
    
            if (model.isRunning())
                view.tv_status.visibility = View.GONE
            else
                view.tv_status.apply {
                    visibility = View.VISIBLE
                    setText(R.string.showEnded)
                }
        }
    
    override fun unbindView(holder: ViewHolder)
        {
            super.unbindView(holder)
    
            holder.view.apply {
                tv_status.text = ""
                tv_nameAndYear.text = ""
                iv_showImage.setImageDrawable(null)
            }
        }
    

    Things i have tried (inside unbindView method)

    i found a few suggested solutions on StackOverflow but none of them work for me

    • imageView.setImageDrawable(null)
    • imageView.setImageBitmap(null)
    • imageView.setImageResource(0)
    • imageView.setImageResource(android.R.color.transparent)

    up until today imageView.setImageDrawable(null)has been working just fine but not anymore for some reason... is my code wrong somehow? is anybody else experiencing this issue?

    question unrelated 
    opened by or-dvir 21
  • Fast Adapter 4 - First Impressions

    Fast Adapter 4 - First Impressions

    Hi there, i have just migrated my large project to Fast Adapter 4 (Kotlin). It costs me about 2 days with 6 hours work each day because i use this lib in first place to my app and it's little difficult to find some good examples when using this lib from Kotlin project too.

    I just wanted to say that for the moment everything seems to be working OK (Comparator, Filter, Listeners, ItemAdapter etc.)

    enhancement 
    opened by eakteam 20
  • List Not Update

    List Not Update

    Hi everyone, I was follow the all API step by step using fastadapter. I have some problem. When I search some query and update the item, then on the list is not update (until I touch the screen).

    I use search view:

                @Override
                public boolean onQueryTextSubmit(String query) {
    
                    if(!querySearch.equals(query)){
                        querySearch = query; // the query search
    
                        // 1. First, clear the array of data
                        fastItemAdapter.clear();
    
                        // 2. Notify the adapter of the update
                        fastItemAdapter.notifyDataSetChanged();
                        // fastItemAdapter.notifyAdapterDataSetChanged();
    
                        // 3. Reset endless scroll listener when performing a new load
                        endlessRecyclerOnScrollListener.resetPageCount();
                    }
    
                    return true;
                }
    

    The Layout Grid:

       GridLayoutManager gridLayoutManager = new GridLayoutManager(ChooseUserActivity.this, 3);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                switch (fastItemAdapter.getItemViewType(position)) {
                    case R.id.fastadapter_progress_item_id:
                        return 3;
                    case R.id.fastadapter_user_item_id:
                        return 1;
                    default:
                        return -1;
                }
            }
        });
    

    Wrapper:

       recyclerView.setAdapter(footerAdapter.wrap(fastItemAdapter));
    

    I Dont how to fix it, because I was log the request URL and it response the data, but on the list (recyleview) somethimes not showing (until I touch or scroll the screen)

    *NOTE: when I remove the footerAdapter (not using footer adapter) then it working good. But I need loading animation on footer so I use footer Adapter :'(

    question 
    opened by tomeroto 20
  • Issues with expandable items (wrong items are collapsed with mutli level items)

    Issues with expandable items (wrong items are collapsed with mutli level items)

    About this issue

    Issue

    When I have expandable items (each level implements IExpandable and all use auto expand) that look like following:

    • Top 1
      • Sub 1.1
        • SubSub 1.1.1
        • SubSub 1.1.2
        • SubSub 1.1.3
      • Sub 1.2
    • Top 2

    And I click Top 1, then SubSub 1.1.2 and SubSub 1.1.3 are not removed. Seems like FastAdapter does not sum up all sub items (including nested ones) when it collapses a parents items but only direct children.

    Note

    I found out that isOnlyOneExpandedItem in the expandable extension only works at the lowest level (at Sub Sub level in the example above) - it would be nice to allow one expanded item at each level only as well, this was actually what I was expecting.

    Details

    • Used library version: 5.0.0
    • android x recyclerview: 1.1.0

    Setup looks like following:

    fastAdapter = FastAdapter.with(itemAdapter)
                .withSavedInstanceState(savedInstanceState)
    
    fastAdapter.getExpandableExtension().apply {
    	//isOnlyOneExpandedItem = true
    }
    

    And my items look like following:

    class Item(
        val data: TopData,
        val childItems: MutableList<ChildItem>
    ) : AbstractItem<Item.ViewHolder>(), IExpandable<Item.ViewHolder> {
    	// ...
    }
    
    class SubItem(
        val data: SubData,
        val childItems: MutableList<SubSubItem>
    ) : AbstractItem<SubItem.ViewHolder>(), IExpandable<SubItem.ViewHolder> {
    	// ...
    }
    
    class SubSubItem(
        val data: SubSubData
    ) : AbstractItem<SubSubItem.ViewHolder>(), IExpandable<SubSubItem.ViewHolder> {
    	// ...
    }
    
    question 
    opened by MFlisar 18
  • DefaultItemListImpl vs. multithread

    DefaultItemListImpl vs. multithread

    So I've been trying to understand the most frequent crashes Firebase reports for my app.

    Here's a preview of a typical case, on every Android version and many phone models (302 similar crashes for 220 user in the last 24 hours) :

    Fatal Exception: java.lang.IndexOutOfBoundsException: Index: 25, Size: 1
           at java.util.ArrayList.get(ArrayList.java:437)
           at com.mikepenz.fastadapter.utils.DefaultItemListImpl.get(DefaultItemListImpl.java:23)
           at com.mikepenz.fastadapter.adapters.ModelAdapter.getAdapterItem(ModelAdapter.java:168)
           at com.mikepenz.fastadapter.FastAdapter.getItem(FastAdapter.java:507)
           at com.mikepenz.fastadapter.FastAdapter.getItemViewType(FastAdapter.java:581)
           at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6186)
           at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
           at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
           at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
           at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
           at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
           at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
           at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
           at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
           at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
           at android.view.View.layout(View.java:23753)
           at android.view.ViewGroup.layout(ViewGroup.java:7277)
           at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1855)
           at android.view.View.layout(View.java:23753)
           at android.view.ViewGroup.layout(ViewGroup.java:7277)
           at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
           at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
           at android.view.View.layout(View.java:23753)
           at android.view.ViewGroup.layout(ViewGroup.java:7277)
           at androidx.recyclerview.widget.RecyclerView$LayoutManager.layoutDecoratedWithMargins(RecyclerView.java:9587)
           at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1685)
           at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
           at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
           at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
           at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
           at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
           at android.view.View.layout(View.java:23753)
           at android.view.ViewGroup.layout(ViewGroup.java:7277)
           at androidx.viewpager2.widget.ViewPager2.onLayout(ViewPager2.java:527)
           at android.view.View.layout(View.java:23753)
           at android.view.ViewGroup.layout(ViewGroup.java:7277)
           at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1855)
           at android.view.View.layout(View.java:23753)
           at android.view.ViewGroup.layout(ViewGroup.java:7277)
           at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
           at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
           at android.view.View.layout(View.java:23753)
           at android.view.ViewGroup.layout(ViewGroup.java:7277)
           at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
           at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
           at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
           at android.view.View.layout(View.java:23753)
    

    The calling code is classic stuff

    compositeDisposable.add(Single.fromCallable(() -> FastAdapterDiffUtil.INSTANCE.calculateDiff(itemAdapter, contentItems))
                        .subscribeOn(Schedulers.computation())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(diffResult -> {
                            FastAdapterDiffUtil.INSTANCE.set(itemAdapter, diffResult);
                            differEndCallback();
                        })
                );
    

    The more I'm thinking about this, the more I've come to believe this issue could be the consequence of DefaultItemListImpl's list being used by different threads.

    The following scenario is very likely in the case of my app -though I can't repro it- :

    1. Initial list has 50 items
    2. The list is updated by LiveData from 50 items to 1 item after a search query
    3. Meanwhile, the displayed RecyclerView still tries to access item 25 (i.e. what we see in the stacktrace above)

    In my opinion, this is likely to happen when the user browses his books very quickly on a slow device (where UI doesn't quite catch up with the flux of data from the DB).

    My question is as follows : what would be the best approach to fix that problem ?

    I'd suggest the following changes on DefaultItemListImpl :

    • Use Collections.synchronizedList() on DefaultItemListImpl._items and use synchronized on every class method that manipulates the list
    • Perform a simple range test on get and set to make certain we don't access stuff outside the list range

    What's your take about these ? 😄

    question good to know 
    opened by RobbWatershed 16
  • Drag & drop - animation is broken

    Drag & drop - animation is broken

    About this issue

    I see the same issue like in the video here: #991 and I do use stable ids in my adapter...

    What I see is following

    • I start a drag
    • I stop it => itemTouchDropped is called followed by itemTouchStopDrag (which seems to be intended, although it seems wrong imho)
    • I update my data in itemTouchDropped => this triggers a data update and updates the adapter data which may happen during a running animation...

    Problem

    • itemTouchStopDrag stops the drag animation, this means the item appears at its original position again although the back animation move animation is still running
    • ghost views as in the mentioned other issues video

    Work around

    I delay the the drop data update until the itemTouchStopDrag is called after a drop.

    Here's my code:

    private val dragCallback = SimpleDragCallback(object : ItemTouchCallback {
    
            var updatedItems: List<IDataItem>? = null
    
            override fun itemTouchOnMove(oldPosition: Int, newPosition: Int): Boolean {
                DragDropUtil.onMove(itemAdapter, oldPosition, newPosition)  // change position
                return true
            }
    
            override fun itemTouchDropped(oldPosition: Int, newPosition: Int) {
                L.d { "Dropped: $oldPosition => $newPosition" }
                if (oldPosition == newPosition) {
                    // drag drop to same position starts the selection mode
                    select(activity, oldPosition)
                } else {
                    val items = itemAdapter.adapterItems.map { it.data }
                    items.forEachIndexed { index, item ->
                        item.order = index
                    }
                    updatedItems = items
                }
            }
    
            override fun itemTouchStartDrag(viewHolder: RecyclerView.ViewHolder) {
                L.d { "Drag start..." }
            }
    
            override fun itemTouchStopDrag(viewHolder: RecyclerView.ViewHolder) {
                L.d { "Drag stop..." }
                updatedItems?.let {
                    GlobalScope.launch(Dispatchers.IO) {
                        DataManager.update(it)
                    }
                }
                updatedItems = null
            }
        }).apply {
            notifyAllDrops = true
            isDragEnabled = true
        }
    

    Question

    What's the reason to not delay the itemTouchDropped until after itemTouchStopDrag? This seems unlogical to me...

    Details

    • [x] Used library version 5.7.0
    opened by MFlisar 0
  • EventHook + RecycledViewPool

    EventHook + RecycledViewPool

    About this issue

    Hello! I've recently started to combine a series of consecutive Fragment RecyclerViews with RecycledViewPool to bump performance up via View pooling. However, it seems like that does not work too well with the FastAdapter EventHook mechanism (onPostCreateViewHolder is no longer called for "pooled" Views from following Fragments, old, no-longer-valid hooks are being reused (because of tag-based attachment?)) Any ideas on how to properly manage that case?

    Best regards, Illia

    Details

    • Used library version 5.6.0
    opened by dummyco 3
  • Clicked expandable item does not expand sometimes

    Clicked expandable item does not expand sometimes

    I need an expandable multi-level list where only one of top-level items can be expanded at a time but there is no such restrictions on lower levels (multiple items can be expanded there). Built-in isOnlyOneExpandedItem can't be used for that so I've implemented an onPreClickListener where I'm checking if top-level item is getting expanded, if so I'm collapsing everything else (items expanded on lower levels will be also collapsed and this is also expected).

    It works fine if clicked item is above already expanded one but in an opposite case (expanding something below already expanded one) then clicked item is not getting expanded, only the previous expanded one gets collapsed.

    • How can the issue be reproduced / sample code Look at the fork: https://github.com/koral--/FastAdapter/commit/e5dd30cd5f0284e02af026b07491d0ef5409597d

    Steps to reproduce:

    1. launch expandable sample
    2. collapse everything
    3. expand Test 6 item
    4. click on Test 3 item (it gets expanded and Test 6 gets collapsed - as expected)
    5. click on Test 6 item (Test 3 gets collapsed but Test 6 is not getting expanded)

    What I've tried so far:

    1. returning true from onPreClickListener and toggling clicked item state manually
    2. adding notifyDataSetChanged call

    Details

    • [ ] Used library version - as on current develop tip cab93daa850d8ce848aa025a5b706f423f869ada
    • [ ] Used support library version - as on current develop tip cab93daa850d8ce848aa025a5b706f423f869ada
    • [ ] Used gradle build tools version - as on current develop tip cab93daa850d8ce848aa025a5b706f423f869ada
    • [ ] Used tooling / Android Studio version Android Studio Bumblebee | 2021.1.1 Canary 1 Build #AI-203.7717.56.2111.7361063, built on May 14, 2021 Runtime version: 11.0.10+0-b96-7281165 x86_64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. macOS 11.4 GC: G1 Young Generation, G1 Old Generation Memory: 8192M Cores: 8 Registry: external.system.auto.import.disabled=true Non-Bundled Plugins: String Manipulation, com.knziha.vectorpathtweaker, org.exbin.deltahex.intellij, mobi.hsz.idea.gitignore, Dart, com.localizely.flutter-intl, org.jetbrains.kotlin, io.flutter, kotest-plugin-intellij, org.intellij.plugins.markdown
    • [ ] Other used libraries, potential conflicting libraries

    Checklist

    enhancement help wanted 
    opened by koral-- 1
  • IOOB exception when using DiffUtil on separate thread

    IOOB exception when using DiffUtil on separate thread

    About this issue

    When using FastAdapterDiffUtil.calculateDiff() on any thread different from Main, there is a chance of IndexOutOfBoundsException being thrown. It is reproducible on modified DiffUtilActivity from FastAdapter's sample: https://github.com/boguszpawlowski/FastAdapter/blob/diffutil_bug/app/src/main/java/com/mikepenz/fastadapter/app/DiffUtilActivity.kt Steps to reproduce:

    • Open DiffUtil Screen
    • Start scrolling
    • After hitting a specific time window, a crash will happen:
    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.mikepenz.fastadapter.app, PID: 2075
        java.lang.IndexOutOfBoundsException: Index: 26, Size: 19
            at java.util.ArrayList.get(ArrayList.java:437)
            at com.mikepenz.fastadapter.utils.DefaultItemListImpl.get(DefaultItemListImpl.kt:23)
            at com.mikepenz.fastadapter.adapters.ModelAdapter.getAdapterItem(ModelAdapter.kt:168)
            at com.mikepenz.fastadapter.FastAdapter.getItem(FastAdapter.kt:507)
            at com.mikepenz.fastadapter.FastAdapter.getItemViewType(FastAdapter.kt:581)
            at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5978)
            at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6158)
            at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
            at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
            at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
            at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
            at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
            at androidx.recyclerview.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1391)
            at androidx.recyclerview.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1128)
            at androidx.recyclerview.widget.RecyclerView.scrollStep(RecyclerView.java:1841)
            at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5302)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1031)
            at android.view.Choreographer.doCallbacks(Choreographer.java:854)
            at android.view.Choreographer.doFrame(Choreographer.java:785)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1016)
            at android.os.Handler.handleCallback(Handler.java:914)
            at android.os.Handler.dispatchMessage(Handler.java:100)
            at android.os.Looper.loop(Looper.java:224)
            at android.app.ActivityThread.main(ActivityThread.java:7560)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
    

    Observations:

    • Error only occurs when diff calculation is made on thread different from Main
    • Error only occurs when you are interacting with a screen in the same time (e.g. scrolling) and large number of items is removed.

    My conclusion: If diff calculation is happening at the same time as some changes on the screen (user interaction, change in view hierarchy), and is done concurrently, due to item list modified and read on different threads, crash can happen.

    Details

    • Used library version - 5.3.5
    • Used support library version - N/A
    • Used gradle build tools version - 4.1.2
    • Used tooling / Android Studio version - Arctic Fox 2021 Canary 4
    • Other used libraries, potential conflicting libraries - N/A

    Checklist

    Similar/Connected issues: https://github.com/mikepenz/FastAdapter/issues/772 - potential solution https://github.com/mikepenz/FastAdapter/issues/959 - key difference is that I'm NOT using Objects.hash for creating id, they are 100% stable and unique.

    help wanted 
    opened by boguszpawlowski 5
  • Support for Android Paging 3

    Support for Android Paging 3

    https://developer.android.com/topic/libraries/architecture/paging/v3-overview

    Not really an urgency as it is still in alpha phase, but definitely something to plan for the middle term imho.

    enhancement help wanted 
    opened by RobbWatershed 5
  • Expandable + filtering - crash and problems

    Expandable + filtering - crash and problems

    General problem In general, if you use expandable items and filtering together, you always lose the expandable state during filtering. This is really a problem if you want to filter and suddenly the expanded item containing the item that you want to filter out is gone because it's parent is collapsed. Additionally expanding an item while the filter is active does not respect the current active filter either it seems, I see that always all children of an item are expanded regardless of the current filter.

    Crash A side effect of this behaviour is following crash if you collapse/expand items after filtering your views.

    If desired, I can give you an example code with a little library that I'm rewritting currently in kotlin which is not far yet but can reproduce this issue easily.

    Exception

    kotlin.TypeCastException: null cannot be cast to non-null type kotlin.collections.List<Item>
        at com.mikepenz.fastadapter.adapters.ItemFilter.publishResults(ItemFilter.kt:104)
        at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:6986)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
    

    Details

    • [ ] Used library version: 5.0.0
    enhancement help wanted 
    opened by MFlisar 2
Releases(v5.7.0)
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
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
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
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
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
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
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
This library provides Easy Android ListView Adapters(EasyListAdapter & EasyCursorAdapter) which makes designing Multi-Row-Type ListView very simple & cleaner, It also provides many useful features for ListView.

EasyListViewAdapters Whenever you want to display custom items in listview, then only way to achieve this is to implement your own subclass of BaseAda

Biraj Patel 132 Nov 25, 2022
Just like instant coffee, saves 78% of your time on Android's Custom Adapters.

Notice Instant Adapter is now part of an even more awesome Adapter Kit project! Instant Adapter Just like instant coffee, saves 78%* of your time on A

Ragunath Jawahar 232 Nov 25, 2022
[] Easy Adapters library for Android

Deprecated Due to the growing use of the RecyclerView and the RecyclerView.Adapter provided adapter class, Easy-Adapter is now deprecated. Whilst the

ribot 425 Nov 25, 2022
Open source routing engine for OpenStreetMap. Use it as Java library or server.

GraphHopper Routing Engine GraphHopper is a fast and memory efficient Java routing engine, released under Apache License 2.0. By default it uses OpenS

GraphHopper 4k Jan 7, 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
This library provides GridAdapters(ListGridAdapter & CursorGridAdapter) which enable you to bind your data in grid card fashion within android.widget.ListView, Also provides many other features related to GridListView.

GridListViewAdapters This libarary enables you to implement GridView like card layout within ListView with added capabilites like Paginations, Additio

Biraj Patel 270 Nov 25, 2022
Vector map library and writer - running on Android and Desktop.

Mapsforge See the integration guide and changelog. And read through how to contribute guidelines. If you have any questions or problems, don't hesitat

mapsforge 1k Jan 2, 2023
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
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