2

I want to create a dynamic loading view that contains horizontal recyclerview inside vertical recyclerview and vertical recyclerview should be inside Scrollview as the main view contains some more views components. So my dynamic hierarchy is as following:-

 Scrollview [
  | Viewpager --
  | AdView --
  | Vertical Items - Recyclerview {
       1) [Horizontal Recyclerview {1.1, 1.2, 1.3} [Lazy Loading of Items]]
       2) [Horizontal Recyclerview {2.1, 2.2, 2.3} [Lazy Loading of Items]]
       3) [Horizontal Recyclerview {3.1, 3.2, 3.3} [Lazy Loading of Items]]
       4) [Horizontal Recyclerview {4.1, 4.2, 4.3} [Lazy Loading of Items]]
       .
       .
       .
    [Lazy Loading of Items in Vertical Direction also]
       }
   | Some Another View --
          ]

Is there any best way to achieve this type of view in android. So dynamic loading of items can be achieved in both horizontal and vertical directions ? Are there any lib available in android ? Please suggest me some good examples of this.

Anas
  • 971
  • 13
  • 28
moody_user
  • 41
  • 1
  • 4
  • Just looking by your hierarchy I can say that you will face the problem of scroll inside scroll, and probably your view pager will not show the content of your fragments if it does not have a fixed height. Are you able to make the view pager work with the scroll view? I can't help you with the lazy-loading problem, but maybe I can help you with the scroll problem if you have it. – Roni Castro Mar 18 '18 at 08:10
  • This is a simple project that I've made to fix this kind of view pager with scroll view problem: https://github.com/roni-castro/multiple-scroll-solution – Roni Castro Mar 18 '18 at 09:18
  • @RoniCastro Do you think that this would solve the problem of Scrolling Behavior ? – moody_user Mar 19 '18 at 13:41
  • It would necessary to see the code or your layout, but the main problem of view pager is that it does not work very well with scrollView or nestedScrollView, and it there's a recycler view inside the fragment it's necessary to remove it's scroll by setting the property setNestedScrollingEnable(false) to avoid slow scroll. If you require a pagination of the items of your recyclerview this might be another problem. – Roni Castro Mar 19 '18 at 21:48
  • Here are some links that helped me solve this scroll problem: https://stackoverflow.com/questions/30580954/viewpager-in-a-nestedscrollview https://stackoverflow.com/questions/47887875/how-to-use-viewpager-inside-nestedscrollview-with-a-view-top-of-viewpager https://www.linkedin.com/pulse/android-viewpager-nestedscrollview-bukhori-aqid/ – Roni Castro Mar 19 '18 at 21:49
  • @RoniCastro I think you got it in a wrong direction man, Vertical Recyclerview is not inside in Viewpager fragment. All main views components are vertical in order. First there will be viewpager for some auto scrolling items. Then second view is adview and then I need to set a dynamic vertical recyclerview of lazy loading items which would be containing horizontal recyclerview items(lazy loading). All I need to set views in a scroll view component. – moody_user Mar 20 '18 at 06:11

1 Answers1

2

The best way is to use the RendererRecyclerViewAdapter

Step 1: add ViewModel interface to your simple item

public class SimpleItem implements ViewModel {
    /* your getters */
}

Step 2: Create ViewBinder for your simple item

private ViewRenderer getSimpleViewBinder() {
    return new ViewBinder<>(
        R.layout.simple_item, /* your item layout */
        SimpleItem.class, /* your model class */
        (model, finder, payloads) -> {
            /* your binding */
            finder.setText(R.id.textView, model.getText());
    });
}

Step 3: Extend DefaultCompositeViewModel and add an uniq ID of your horizontal item

public class HorizontalViewModel extends DefaultCompositeViewModel {

    private int mID;

    public HorizontalViewModel(int ID, List<? extends ViewModel> items) {
        super(items);
        mID = ID;
    }

    public int getID() {
        return mID;
    }
}

It is your Horizontal item that contains all simple items inside.

Step 4: Create HorizontalViewBinder

public class HorizontalViewBinder extends CompositeViewBinder<HorizontalViewModel> {

    public HorizontalViewBinder(int layoutID,
                                int recyclerViewID,
                                Class<HorizontalViewModel> type) {
        super(layoutID, recyclerViewID, type);
    }

    @Override
    public void bindView(HorizontalViewModel model, CompositeViewHolder holder) {
        super.bindView(model, holder);
        holder.getRecyclerView().addOnScrollListener(new EndlessScrollListener() {
            @Override
            public void onLoadMore(int page, int totalItemsCount) {
                holder.getAdapter().showLoadMore();
                /* sendLoadMoreRequest(model.getID()); */
            }
        });
    }

    @NonNull
    @Override
    public CompositeViewHolder createViewHolder(ViewGroup parent) {
        final CompositeViewHolder viewHolder = super.createViewHolder(parent);
        viewHolder.getAdapter().registerRenderer(new LoadMoreViewBinder(R.layout.load_more)); 
        /* don't forget to create load more layout */
        return viewHolder;
    }
}

Step 5: Create a getter for your HorizontalViewBinder

private ViewRenderer getHorizontalViewBinder() {
    return new HorizontalViewBinder<>(
        R.layout.horizontal_layout, /* your horizontal layout that contains RecyclerView */
        R.id.recycler_view, /* an ID of RecyclerView */
        HorizontalViewModel.class /* your created class, see Step 3 */
    );
}

Step 6: Initialize in your Fragment/Activity the main RendererRecyclerViewAdapter

RendererRecyclerViewAdapter mRecyclerViewAdapter = new RendererRecyclerViewAdapter();
mRecyclerViewAdapter.registerRenderer(new Horizontal().registerRenderer(getHorizontalViewBinder().registerRenderer(getSimpleViewBinder())); /* register HorizontalViewBinder and SimpleViewBinder */
mRecyclerViewAdapter.setItems(getYourList());

Step 7: Add LoadMoreListener to main RecyclerView

mRecyclerView.addOnScrollListener(new EndlessScrollListener() {
    @Override
    public void onLoadMore(int page, int totalItemsCount) {
        mRecyclerViewAdapter.showLoadMore();
        /* send request to a server */
    }
});

Step 8: Create specials ViewBinders for other your items: AdViewBinder, SomeAnotherViewBinder and register them in your adapter. See the Step 1 and the Step 2.


FYI: EndlessScrollListener - it is your implementation of LoadMoreListener

Enjoy! :)

If you need more details please see wiki-pages: Simple Items, Composite Items, Load More Indicator.

Vitaly
  • 549
  • 1
  • 6
  • 14