MultiItem Advanced Implementation of Head Foot and Loading More-Type RecyclerView Adapter

Keywords: Java github REST less

Preface

This article is an advanced article in the MultiItem series. It focuses on the usage and implementation of header footer and drop-down refresh loading for more functions. MultiItem Usage and Detailed-Elegant Implementation of Multi-Type RecyclerView Adapter Some basic usages and dependencies are explained. Students who haven't seen them can click on them.
MutliItem mainly solves the multi-type Recycler View Adapter problem. It achieves zero coding of Adapter in normal use, liberates complex Adapter classes and improves scalability.
The positioning of this library is not large and complete, but it will try to be simple and practical.

Source address

Github address: https://github.com/free46000/MultiItem Please pay more attention. More updates will be first shown on GitHub and will be released on this platform in the first time.

Effect screenshots

The picture has been processed for over 10 kb


headfoot

fullspan

loadmore

usage

Add header and footer to the list

Adding header footer provides two ways, directly addView or addItem:

//Register XXManager Management Class for XXBean Data Source
adapter.register(TextBean.class, new TextViewManager());

//Add header
TextView headView = new TextView(this);
headView.setText("adopt addHeadView Increased head1");
//Mode 1: Convenient for practical business use
adapter.addHeadView(headView);
//Mode 2: This approach is the same as adding data sources directly to addDataItem
adapter.addHeadItem(new TextBean("adopt addHeadItem Increased head2"));

//Add footer in the same way as adding header
TextView footView = new TextView(this);
footView.setText("adopt addFootView Increased foot1");
adapter.addFootView(footView);
adapter.addFootItem(new TextBean("adopt addFootItem Increased foot2"));

Add a full width Item (including header and footer) to the table

For full width, see ViewHolderManager#isFullSpan returning true for head foot or any data source Item

//Register the FullSpanTextViewManager management class for the TextBean data source here
adapter.register(TextBean.class, new FullSpanTextViewManager());

//Add header or footer
TextView headView = new TextView(this);
headView.setText("adopt addHeadView Increased head1");
//The isFullSpan method has been implemented using HeadFootHolderManager, which defaults to full width
adapter.addHeadView(headView);

//Add normal Item, see FullSpanTextView Manager for details, default full width
adapter.addDataItem(new TextBean("FullSpanTextViewManager Full width Item"));

Use of drop-down refresh to load more functions

Swipe Refresh Layout is not used in drop-down refresh. It's easy to turn on and handle loading more functions, but it's important to note that loading more is essentially a footer and is sensitive to adding order, so you need to go to addFoot first and then call the opening method:

//Open Loading More Views
adapter.enableLoadMore(new LoadMoreHolderManager(this::loadData));

//Load complete isLoadAll: Is all data available?
adapter.setLoadCompleted(boolean isLoadAll);

//Failed to load
adapter.setLoadFailed();

Through the open method, we can see that we rely on LoadMoreHolder Manager, mainly to deal with the changes of loading more interfaces in different states. The following code is posted. For more implementation details, see LoadMoreManager:

/**
 * Load more view management classes
 */
public class LoadMoreHolderManager extends LoadMoreManager {

    public LoadMoreHolderManager(OnLoadMoreListener onLoadMoreListener, boolean isAutoLoadMore) {
        super(onLoadMoreListener, isAutoLoadMore);
    }

    @Override
    protected int getItemLayoutId() {
        return R.layout.item_load_more;
    }

    @Override
    protected void updateLoadInitView() {
        ((TextView) getView(loadMoreView, R.id.text)).setText("");
    }

    @Override
    protected void updateLoadingMoreView() {
        ((TextView) getView(loadMoreView, R.id.text)).setText(R.string.loading_more);
    }

    @Override
    protected void updateLoadCompletedView(boolean isLoadAll) {
        ((TextView) getView(loadMoreView, R.id.text))
                .setText(isLoadAll ? R.string.load_all : R.string.load_has_more);
    }

    @Override
    protected void updateLoadFailedView() {
        ((TextView) getView(loadMoreView, R.id.text)).setText(R.string.load_failed);
    }
}

So far, the header footer and drop-down refresh of this library have been used to load more functions. The RecyclerView Adapter class has not been modified or inherited, and the BaseItemAdapter can be implemented by default.

Detailed explanation

header and footer

Making use of the multi-type characteristics of Multiitem, we encapsulate the practical api. In BaseItem Adapter, we maintain two sets of headItems footItems, and acquire the data in order when getItem is done. The following is the following:

/**
 * @param position int
 * @return Returns Item at the specified location
 */
public Object getItem(int position) {
    if (position < headItems.size()) {
        return headItems.get(position);
    }

    position -= headItems.size();
    if (position < dataItems.size()) {
        return dataItems.get(position);
    }

    position -= dataItems.size();
    return footItems.get(position);
}

Add a full width Item to the table

Two methods are encapsulated in ViewHolder Manager to fit the width of the table layout:

/**
 * @return Fill in the parent layout
 * @see StaggeredGridLayoutManager.LayoutParams#setFullSpan
 * @see GridLayoutManager#setSpanSizeLookup
 */
public boolean isFullSpan() {
    return fullSpan;
}

/**
 * Get the current span size based on spanCount (for table layout)
 * If it is set to a positive integer, it returns; if it is full Span, it returns spanCount; the rest returns 1.
 * GridLayoutManager Under the mode, adjust the return value of this method to achieve the function of different Item occupying different widths
 *
 * @param spanCount span Total quantity
 * @return Current span size
 * @see GridLayoutManager#setSpanSizeLookup
 */
public int getSpanSize(int spanCount) {
    return spanSize > 0 ? spanSize : (isFullSpan() ? spanCount : 1);
}

Load more

Loading makes more use of onBindViewHolder, the callback method of RecyclerView Adapter, to encapsulate the template method of loading more view states, and provides corresponding processing methods. See LoadMoreManager for details. Here is the key code:

@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, @NonNull Object o) {
    if (isNeeLoadMore(holder)) {
        if (isAutoLoadMore()) {
            //Called when more data can be loaded and automatic loading is turned on
            onLoadMore();
        }
    } else {
        updateLoadInitView();
    }
}

/**
 * Avoid loading data when first visible
 * If the number of head and foot is less than the current location of loadMore, it proves that there is no ItemData data, that is, before loading data for RecyclerView.
 *
 * @param holder
 * @return Do you need to load more?
 */
protected boolean isNeeLoadMore(@NonNull BaseViewHolder holder) {
    int headFootCount = adapter.getHeadCount() + adapter.getFootCount();
    return headFootCount < holder.getItemPosition();
}

I hope you will like it and leave more messages to communicate.

Posted by ChompGator on Tue, 11 Dec 2018 13:33:05 -0800