yqritc/RecyclerView-FlexibleDivider

Change the divider size depending not only on the position but also on the content?

MrBrightside29 opened this issue · 4 comments

Hi there,

Is there a way of changing the divider size depending not only on the position but also on the content?
In my case, my adapter extends from a CursorRecyclerAdapter and depending on the position content I set a different view type.

    @Override
    public int getItemViewType(int position) {
        if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
            String cursorUid = mCursor.getString(mCursor.getColumnIndex(ChatProvider.COL_FROM_UID));
            String previousUid = "";
            if (!mCursor.isFirst()) {
                mCursor.moveToPrevious();
                previousUid = mCursor.getString(mCursor.getColumnIndex(ChatProvider.COL_FROM_UID));
                mCursor.moveToNext();
            }

            if (cursorUid.equals(uid))
                return VIEW_TYPE_ME;
            else if (previousUid.equals(cursorUid))
                return VIEW_TYPE_OTHERS_BIS;
            else
                return VIEW_TYPE_OTHERS;

        }
        return 0;
    }

My problem is that I set the adapter to the recyclerview when the cursor is loaded inside the onLoadFinished method of the CursorLoader and the "dividerSize" method seems to get called before the cursor is loaded setting the default divider to all items.

@Override
    public int dividerSize(int position, RecyclerView parent) {
        switch (getItemViewType(position)) {
            case VIEW_TYPE_ME:
                Utils.convertDpToPixel(context.getResources().getDimension(R.dimen.divider_chat_normal), context);
                break;

            case VIEW_TYPE_OTHERS:
                Utils.convertDpToPixel(context.getResources().getDimension(R.dimen.divider_chat_normal), context);
                break;

            case VIEW_TYPE_OTHERS_BIS:
                Utils.convertDpToPixel(context.getResources().getDimension(R.dimen.divider_chat_bis), context);
                break;
        }
        return Utils.convertDpToPixel(context.getResources().getDimension(R.dimen.divider_chat_normal), context);
    }

I've tried to call addItemDecoration after the data is loaded into the cursor with no luck.

   @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        messagesChatAdapter.swapCursor(data);
        recyclerView.scrollToPosition(messagesChatAdapter.getItemCount() - 1);
        recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity())
                .sizeProvider(messagesChatAdapter)
                .color(android.R.color.transparent)
                .build());
    }

@MrBrightside29
how about calling notifyItemDataSetChanged in onLoadFinished?

My recyclerView swapCursor method already calls notifyItemDataSetChanged and swapCursor is being called in onLoadFinished with no difference.

public Cursor swapCursor(Cursor newCursor) {
        if (newCursor == mCursor) {
            return null;
        }
        Cursor oldCursor = mCursor;
        mCursor = newCursor;
        if (newCursor != null) {
            mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
            mDataValid = true;
            // notify the observers about the new cursor
            notifyDataSetChanged();
        } else {
            mRowIDColumn = -1;
            mDataValid = false;
            // notify the observers about the lack of a data set
            notifyItemRangeRemoved(0, getItemCount());
        }
        return oldCursor;
    }

I believe dividerSize should be called when notifyDataSetChanged is called.
So, please check if dividerSize is called after swapCursor is executed.

It was a silly mistake. I missed the return statement inside each case of the switch as you can see.
Sorry for making you lose time and thanks for your help.