Code Monkey home page Code Monkey logo

mjolnirrecyclerview's Introduction

[DEPRECATED] MjolnirRecyclerView - This library is no longer maintained and it will not receive any more updates.

==========

CircleCI JCenter Method count Android Arsenal

Provides a simple way to extend the default RecyclerView behaviour with support for headers, footers, empty view, DiffUtil and ArrayAdapter like methods.

Usage

Add the library as a dependency to your build.gradle

compile 'co.infinum:mjolnirrecyclerview:version@aar'

Check the latest version here.

Features

1. Header & footer support

Add a custom number of headers and footers to MjolnirRecyclerView by using 2 simple methods from MjolnirRecyclerAdapter:

    adapter.setHeader(View view)
    adapter.setHeader(View view)

2. Empty view

Empty view support for MjolnirRecyclerView. View is automatically hidden when adapter is populated with some data, and is automatically shown once again when adapter becomes empty.

    recyclerView.setEmptyView(View view)

You can also show empty view while adapter is not set to the MjolnirRecyclerView, which is handy if you want to intialize adapter at some later point in the time.

    // show empty view if adapter is not set
    recyclerView.setEmptyView(View view, true)

3. DiffUtil

DiffUtil support for MjolnirRecyclerAdapter. Simply add DiffUtil.Callback in adapters update method:

    adapter.update(new ItemDiffUtilResult())

As DiffUtil is a blocking sync action, it's executed on the background thread inside the MjolnirRecyclerAdapter by using a AsyncTask. As a result of this approach, you need to call cancel() method on your adapter when your activity or fragment is about to be destroyed, so that the adapter is not updated if the screen has been destroyed.

    @Override
    protected void onDestroy() {
        super.onDestroy();
        adapter.cancel();
    }

4. ArrayAdapter like methods

MjolnirRecyclerAdapter has full support for ArrayAdapter methods, like add(), addAll(), reset(), remove(), set()...

Contributing

Feedback and code contributions are very much welcome. Just make a pull request with a short description of your changes. By making contributions to this project you give permission for your code to be used under the same license.

Credits

Maintained and sponsored by Infinum.

mjolnirrecyclerview's People

Contributors

anacar avatar dbikic avatar dvasko avatar ikocijan avatar zplesac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mjolnirrecyclerview's Issues

Usage of header

How to implement custom onCreateViewHolder. The situation is I want to create a header that have an image with 2 buttons be added as a header to the listview. How to fetch the layout in onCreateHeaderViewHolder ?

@Override
    protected MjolnirViewHolder onCreateHeaderViewHolder() {
        return new HeaderViewHolder();
    }

    //  Header Holder
    public class HeaderViewHolder extends MjolnirViewHolder<Client> {

        public HeaderViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        protected void bind(Client item, int position, List<Object> payloads) {

        }
    }

qq

Empty View does not seem to work properly.

Empty view is never shown, and it seems to disrupt headers aswell.
Test case:

If I only have a header, and no items in the lists, the entire screen is blank (neither header nor empty view can be seen)

        EventHeaderView header = EventHeaderView_.build(this);
        header.setEvent(eventId);
        mAdapter.addHeader(header, true);

        EmptyView empty = EmptyView_.build(this);
        empty.setText(getString(R.string.HOME_FEED_EMPTY_LIST_TEXT));
        recycler.setEmptyView(empty);

If only the empty view is set (no header, no extra items), it's again completely blank and nothing is showing.

        EventHeaderView header = EventHeaderView_.build(this);
        header.setEvent(eventId);
        //mAdapter.addHeader(header, true);

        EmptyView empty = EmptyView_.build(this);
        empty.setText(getString(R.string.HOME_FEED_EMPTY_LIST_TEXT));
        recycler.setEmptyView(empty);

If we only have the header and no empty view, it behaves as expected, only the header shows.

        EventHeaderView header = EventHeaderView_.build(this);
        header.setEvent(eventId);
        mAdapter.addHeader(header, true);

        EmptyView empty = EmptyView_.build(this);
        empty.setText(getString(R.string.HOME_FEED_EMPTY_LIST_TEXT));
        //recycler.setEmptyView(empty);

And to eliminate the possibility that my empty view is faulty, I tried this:
And the result is that the empty view shows properly as the header.

        EventHeaderView header = EventHeaderView_.build(this);
        header.setEvent(eventId);
        //mAdapter.addHeader(header, true);

        EmptyView empty = EmptyView_.build(this);
        empty.setText(getString(R.string.HOME_FEED_EMPTY_LIST_TEXT));
        mAdapter.addHeader(empty, true);

The expected behaviour when both header and empty views are set, and there are no items present, both should show (empty view below header).

Empty view should ONLY show when extra items are absent.

Wrong item removed from list in UI

The library doesn't seem to take headers into account when removing items.

When I do adapter.remove(item);
It will remove the item before that if I have a header, and if I remove the very first item, it crashes with the following stacktrace:

11-04 14:20:05.422 10076-10076/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: se.thefarm.yourblock, PID: 10076
                                                   java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder{49e503 position=0 id=-1, oldPos=-1, pLpos:-1}
                                                       at android.support.v7.widget.RecyclerView$5.attachViewToParent(RecyclerView.java:692)
                                                       at android.support.v7.widget.ChildHelper.attachViewToParent(ChildHelper.java:239)
                                                       at android.support.v7.widget.RecyclerView.addAnimatingView(RecyclerView.java:1178)
                                                       at android.support.v7.widget.RecyclerView.animateDisappearance(RecyclerView.java:3535)
                                                       at android.support.v7.widget.RecyclerView$4.processDisappeared(RecyclerView.java:456)
                                                       at android.support.v7.widget.ViewInfoStore.process(ViewInfoStore.java:246)
                                                       at android.support.v7.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3385)
                                                       at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3135)
                                                       at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1549)
                                                       at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:305)
                                                       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
                                                       at android.view.Choreographer.doCallbacks(Choreographer.java:580)
                                                       at android.view.Choreographer.doFrame(Choreographer.java:549)
                                                       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
                                                       at android.os.Handler.handleCallback(Handler.java:739)
                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                       at android.os.Looper.loop(Looper.java:135)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Using multiple view types in combination with header crashes

If I use multiple view types such as

@Override
protected int getAdditionalItemViewType(int position) {
     return get(position).getType() == Usage.Type.LABEL ? YEAR : ITEM;
}

and I add header with adapter.setHeader(View view);, method getAdditionalItemViewType will receive wrong positions for items.

Multiple headers and footers issue

We should define how does Mjonir handle cases when we want to add header/footer, but adapter already has defined header and footer.

MjolnirAdapter currently has limitation that it doesn't support multiple headers and views - we can communicate this better to the developer by using one of the few possible solutions:

  1. Throw an exception with some meaningful description when we want to add header/footer to an adapter which already has defined header/footer
  2. Silently fail (this is current behaviour), but log something to the console
  3. Add new addFooter and addHeader methods, which will have an option to force replacing existing header/footer
  4. Combine 1 and 3
  5. Something different

I would like to first address this issue and later add support for multiple headers/footers, as this will probably introduce some breaking changes.

@kjurkovic @ikocijan @reisub what's your opinion about this?

Hide old empty view after setting new one

Currently when you are using one empty view and then set new empty view (with empty list), old empty view stays visible and then you have both old and new empty view visible.

Probably would be better if library hide old empty view when setting new one.

Typo in README.md

For section "1. Header & footer support" of the README.md file, "adapter.setHeader(View view)" is shown twice, when it should only be shown once, and "adapter.setFooter(View view)" be shown for the second entry.

Index manipulation

In ArrayAdapter methods, we don't need to subtract footer.size() from index, only headers.size()

Updates to array adapter methods

Add method overloading for array adapter methods so that the consumer can decide whether the notifyDataSetChanged() should be called.

Make hasHeader() protected

There is private hasHeader() method in MjolnirRecyclerAdapter. It would be great if you can make it protected. It would be useful, for example, when you need to call notifyItemChanged method and you need to calculate the exact position of the item. In that case you'll need to know whether or not header is added.

IllegalStateException when adding data from onScrolledToNextPage method without any delay

If RecyclerView has less items than it can maximum has visible (ie. RecyclerView can take 5 items on the screen, but adapter contains only 3 items) and it has set nextPageListener then IllegalStateException happens when adding next page without any delay.

Steps to reproduce:

  1. add RecyclerView, set nextPageListener and add just few items in adapter (to take less than recycler size)
  2. in onScrolledToNextPage add few more items (I used addAll method)

Workaround is to wrap code that is in onScrolledToNextPage into some runnable and post it on main handler.

Solution is to use main handler for posting task that would call nextPageListener.onScrolledToNextPage inside of onBindViewHolder method of MjolnirRecyclerAdapter.

Crash when adding one item to empty list

As stated in the title, the library throws an IllegalStateException.

This can be reproduced by passing an empty list to the adapter and then calling the add method:

add(item, 0)

The problem is the library validates if the index is greater or equal to items.size(). Since the list is empty and the index is 0 this validates to true.

Footer view does not work properly

Footer view is in xml defined with match_parent width. However when adding it to adapter it somehow gets to wrap_content and positions progress to left.
this is footer view xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/progress_container"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@color/default_background"
              android:orientation="vertical">

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/android:progressBarStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_margin="@dimen/small_padding"/>
</LinearLayout>

this is how it is rendered: http://take.ms/HJpqX

Same view on ListView footer works properly

Support for multiple ViewHolders

Currently, there is no support for multiple item ViewHolders in MjolnirRecyclerAdapter.

This could easily be solved in 2 different ways, which both give a lot of flexibility to the developers:

  1. Add method with protected visibility to the end of onCreateViewHolder() method. By default, it's implementation will return null as a result. By overriding this method, developers can provide it's custom implementation with different ViewHolders.

  2. Override onCreateViewHolder() and provide custom implementation, but force developers to call super on that method (@callsuper annotation).

Footer/Header not removing properly

If you call addFooter(view, true), then later call removeFooter(), and again call addFooter(view, true) the old footer will still be there, I suspect it has something to do with the FooterViewHolder and HeaderViewHolder classes since they are only updated in onCreateViewHolder.

If you have a very small list, won't this pose a problem with the header/footer never actually updating their contents if you replace the view rather than modifying an existing one?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.