Reputation: 41236
I have a RecyclerView which uses a simple line separator Decoration.
The decoration is fine except when a NEW item is added to the bottom of the recycler and scrolled into view, the decoration is initially drawn in it's final location and then the view underneath scrolls into place, but the decoration doesn't scroll.
The desired behavior would be for the decoration to be drawn in it's starting location and then scroll into position along with the new item.
Here's the relevant portions of the Decoration:
class NormalDecoration extends RecyclerView.ItemDecoration {
private int spacing;
private Drawable drawable;
NormalDecoration(Context context) {
spacing = context.getResources().getDimensionPixelOffset(R.dimen.chat_separator_height);
drawable = ContextCompat.getDrawable(context, R.drawable.chat_divider);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (applySpacing(view, parent)) {
outRect.top += spacing;
}
}
boolean applySpacing(View view, RecyclerView parent) {
int position = parent.getChildAdapterPosition(view);
return position != -1 && position < mItems.size();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int dividerLeft = parent.getPaddingLeft();
int dividerRight = parent.getWidth() - parent.getPaddingRight();
for(int index = parent.getChildCount() - 1 ; index >= 0 ; --index) {
View view = parent.getChildAt(index);
if(applySpacing(view, parent)) {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
int dividerTop = view.getBottom() + params.bottomMargin;
int dividerBottom = dividerTop + spacing;
drawable.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
drawable.draw(c);
}
}
}
}
My Adapter contains the following helper:
class Adapter {
public void add(final int index, final IChatMessageItem item) {
mItems.add(index, item);
notifyItemInserted(index);
}
}
And here's how I add the item to the recycler that results in unacceptable scrolling behavior:
...
adapter.add(index, item);
layout.scrollToPosition(index);
...
Upvotes: 0
Views: 993
Reputation: 34542
You need to use view.getTranslationX()
, getTranslationY()
, and getAlpha()
respectively to animate the decoration along with the view moving.
If you just draw a divider, you might want to use the official support decoration which also does the above mentioned.
I also wrote an article about this in detail here.
Upvotes: 2