Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ItemDecoration overriding getItemOffsets() and animation

I am applying equal margins to my RecyclerView using GridLayoutManager by overriding the getItemOffsets() method (see my code below).

However, when an Object is removed from the adapter the remove animation is called without the offsets. Thus, the anmiation starts at a different position than the object to be removed.

I tried to get the position via getSpanIndex(position) but the position (parent.getChildAdapterPosition(view)) returns NO_POSITION since the object has already been removed from the adapter, when getItemOffsets() is called.

Is there any way to get the offsets in my case?

@Override
public void getItemOffsets(Rect outRect, View view, 
                     RecyclerView parent, RecyclerView.State state) {

    GridLayoutManager mgr = parent.getLayoutManager();
    int position = parent.getChildAdapterPosition(view);

    if (position == RecyclerView.NO_POSITION) {
       // here I need to access the position of the current element
       // and call outRect.set(left, top , right, bottom);
       // which is not possible because it is no longer in the adapter
        return;
    } 

    int spanCount = mgr.getSpanCount();
    int spanSize = mgr.getSpanSizeLookup().getSpanSize(position);
    int spanIndex = mgr.getSpanSizeLookup().getSpanIndex(position, spanCount);

    if (spanIndex == spanCount-1) {
        // last element
        left = space / 2;
        right = space;
    } else if (spanIndex == 0) {
        // first element
        left = space;
        right = space / 2;
    } else {
        // middle element
        left = space / 2;
        right = space / 2;
    }
    outRect.set(left, top, right, bottom);
}
like image 227
jeff_bordon Avatar asked Jan 03 '16 11:01

jeff_bordon


People also ask

How to get the offset of an item in itemdecorations?

All ItemDecorations are drawn in the order they were added, before the item views (in onDraw () and after the items (in onDrawOver (Canvas, RecyclerView, RecyclerView.State). Retrieve any offsets for the given item. This method is deprecated. Use getItemOffsets (Rect, View, RecyclerView, State)

Is the getitemoffsets method deprecated?

This method is deprecated. Use getItemOffsets (Rect, View, RecyclerView, State) Draw any appropriate decorations into the Canvas supplied to the RecyclerView. This method is deprecated. Override onDraw (Canvas, RecyclerView, RecyclerView.State)

What is itemdecoration and how to use it?

An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter’s data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more. We can not simply say that ItemDecoration is just a divider with a fancy name. It’s much more than that.

How to do more than visibility with item decorator?

In case you want to do just more than visibility, item decorations are flexible. In the above image for the last item in the group divider fills the entire width. Other dividers have a margin of 56dp to their left side. Here is the ItemDecorator’s onDraw code.


1 Answers

Try using the views LayoutParams. If you don't use some custom LayoutManager, it should contain the information you need.

int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition();
like image 110
David Medenjak Avatar answered Nov 10 '22 09:11

David Medenjak