Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView smoothScrollToPosition on small distance is too fast

In our chat app we use RecyclerView that can have messages with different heights. I want to animate message add with smoothScroll. My problem is: when I use recyclerView.smoothScrollToPosition(position) on messages with small height, it scrolls too fast.

I also tried this solution changing smoothScoll speed, its good for small messages, but when message is big its scroll speed making message appear too slow.

My perfect speed achieves with recyclerView.smoothScrollBy(x, y), but here I have problem getting inserted message height, since messages can have any height.

like image 466
Rafael Avatar asked Feb 10 '17 10:02

Rafael


1 Answers

Override calculateTimeForScrolling method of LinearSmoothScroller that calculate time for all distances:

public class SpeedyLinearLayoutManager extends LinearLayoutManager {

private int smoothScrollDuration;

public SpeedyLinearLayoutManager(Context context, int smoothScrollDuration) {
    super(context);
    this.smoothScrollDuration = smoothScrollDuration;
}

public SpeedyLinearLayoutManager(Context context, int orientation, boolean reverseLayout, int smoothScrollDuration) {
    super(context, orientation, reverseLayout);
    this.smoothScrollDuration = smoothScrollDuration;
}

public SpeedyLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int smoothScrollDuration) {
    super(context, attrs, defStyleAttr, defStyleRes);
    this.smoothScrollDuration = smoothScrollDuration;
}

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {

    final LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {

        @Override
        protected int calculateTimeForScrolling(int dx) {
            return smoothScrollDuration;
        }
    };

    linearSmoothScroller.setTargetPosition(position);
    startSmoothScroll(linearSmoothScroller);
}

public int getSmoothScrollDuration() {
    return smoothScrollDuration;
}

public void setSmoothScrollDuration(int smoothScrollDuration) {
    this.smoothScrollDuration = smoothScrollDuration;
}
}

And use it for recyclerview:

    LinearLayoutManager layoutManager = new SpeedyLinearLayoutManager(context, 100);
    mRecyclerView.setLayoutManager(layoutManager);
like image 125
Hussein Yaqoobi Avatar answered Oct 18 '22 18:10

Hussein Yaqoobi