h6ah4i / android-advancedrecyclerview

RecyclerView extension library which provides advanced features. (ex. Google's Inbox app like swiping, Play Music app like drag and drop sorting)
https://advancedrecyclerview.h6ah4i.com/
Apache License 2.0
5.32k stars 860 forks source link

How to add Header and Footer to DraggableGridExample ? #375

Open belhassen-bc opened 7 years ago

belhassen-bc commented 7 years ago

I saw you added the Header and Footer in the examples (reference to DemoHeaderFooterAdapter). I am quite confused on how to implement them in DraggableGridExampleAdapter.

belhassen-bc commented 7 years ago

I fixed it using the DemoHeaderFooterAdapter along with its interface. On onViewCreated in my adapter, i had to tune the getSpanSize, by adding +1 to the position :

    public int getSpanSize(int position) {
                                int index = (int) mWrappedAdapter.getItemId(position+1);
h6ah4i commented 7 years ago

Hi. If you are trying to use the DemoHeaderFooterAdapter, just wrap the draggable adapter with a DemoHeaderFooterAdapter.

mAdapter = new DraggableGridExampleAdapter(getDataProvider());
mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mAdapter);
mWrappedAdapter = new DemoHeaderFooterAdapter(mWrappedAdapter);

mRecyclerView.setAdapter(mWrappedAdapter);

Also, creating your own header & footer adapter work with GridLayoutManager, you need to set a SpanSizeLookup that returns full-size span for header/footer items. The DemoHeaderFooterAdapter contains the example implementation like below;

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);

    setupFullSpanForGridLayoutManager(recyclerView);
}

// Filling span for GridLayoutManager
protected void setupFullSpanForGridLayoutManager(RecyclerView recyclerView) {
    RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();
    if (!(lm instanceof GridLayoutManager)) {
        return;
    }

    final GridLayoutManager glm = (GridLayoutManager) lm;
    final GridLayoutManager.SpanSizeLookup origSizeLookup = glm.getSpanSizeLookup();
    final int spanCount = glm.getSpanCount();

    glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            final long segmentedPosition = getSegmentedPosition(position);
            final int segment = extractSegmentPart(segmentedPosition);
            final int offset = extractSegmentOffsetPart(segmentedPosition);

            if (segment == SEGMENT_TYPE_NORMAL) {
                return origSizeLookup.getSpanSize(offset);
            } else {
                return spanCount; // header or footer
            }
        }
    });
}

ref.) https://github.com/h6ah4i/android-advancedrecyclerview/blob/0.10.4/example/src/main/java/com/h6ah4i/android/example/advrecyclerview/common/adapter/DemoHeaderFooterAdapter.java#L142

belhassen-bc commented 7 years ago

Thank you :+1:

I forgot to say that your Library is awesome ! I know very few ones that are as great as yours.

Correct me if i am wrong, I need the footer to be like the "+ Manage items" item, I guess this is a normal item, but which is not draggable like others, though it takes the same space and replaces the contiguous previous item if that one gets removed.

Do you think i should not use a Footer at all ? and instead use it as a normal item ? if so, how to disable the dragging animation for only the latest one ?

Otherwise if you agree that this should be a footer, how to make it behave as a normal item ? I mean from size/animation point of view ?

Thank you.

image

h6ah4i commented 7 years ago

Hmm... Good question, but the answer is whichever you want in this case. The "Manage items" item can be implemented both normal item or footer item. If the "Manage items" item can also be draggable, I will recommend you to implement as a normal item.

Case 1 - normal item

Implement some DraggableItemAdapter's methods to disable dragging for the last item.

@Override
public boolean onCheckCanStartDrag(MyViewHolder holder, int position, int x, int y) {
    return position < (getItemCount() - 1);
}

@Override
public ItemDraggableRange onGetItemDraggableRange(MyViewHolder holder, int position) {
    return new ItemDraggableRange(0, getItemCount() - 2);
}

Case 2 - footer item

Create your own wrapper class which extends AbstractHeaderFooterWrapperAdapter.


P.S. Maybe, I will choose implementing the "Manage items" item as a normal item. Because creating a wrapper adapter needs more code to write.

belhassen-bc commented 7 years ago

Excellent !

I would go for a "normal item" as you recommend, but I don't want it to be Draggable, i am giving a try right now, will update you soon.

Thanks a lot !

belhassen-bc commented 7 years ago

One last thing : since I will not need the "standard" footer anymore, what should I remove from the adapter ? I am just making getFooterItemCount return 0, it works indeed, but I guess that a lot of code is not needed there, right ?

Should I tune AbstractHeaderFooterWrapperAdapter ?

public class DemoHeaderFooterAdapter
        extends AbstractHeaderFooterWrapperAdapter<DemoHeaderFooterAdapter.HeaderViewHolder, DemoHeaderFooterAdapter.FooterViewHolder>
        implements View.OnClickListener {