How can I control the scrolling speed of recyclerView.smoothScrollToPosition(position)?
Just to improve on the answer a little:
public class SpeedyLinearLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 5f; //default is 25f (bigger = slower)
public SpeedyLinearLayoutManager(Context context) {
super(context);
}
public SpeedyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public SpeedyLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
final LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return super.computeScrollVectorForPosition(targetPosition);
}
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
And then set SpeedyLayoutManager to your RecyclerView:
recyclerView.setLayoutManager(new SpeedyLinearLayoutManager(context, SpeedyLinearLayoutManager.VERTICAL, false);
How can I control the scrolling speed of recyclerView.smoothScrollToPosition(position)?
Just to improve on the answer a little:
public class SpeedyLinearLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 5f; //default is 25f (bigger = slower)
public SpeedyLinearLayoutManager(Context context) {
super(context);
}
public SpeedyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public SpeedyLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
final LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return super.computeScrollVectorForPosition(targetPosition);
}
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
And then set SpeedyLayoutManager to your RecyclerView:
recyclerView.setLayoutManager(new SpeedyLinearLayoutManager(context, SpeedyLinearLayoutManager.VERTICAL, false);
How to set speed of RecyclerView scroll?
You can create CustomRecyclerView
and slow it down by overriding fling()
method. You can read the official documentation here.
@Override
public boolean fling(int velocityX, int velocityY) {
velocityY *= FLING_SPEED_FACTOR; // keep it less than 1.0 to slowdown
return super.fling(velocityX, velocityY);
}
This simply reduces the fling speed and even with same amount of fling your RecyclerView will scroll lesser.
Android : Control Smooth scroll over recycler view
It's unclear what you mean when you say "smoothScroll
". You could be referring to the automatic "smoothScrollToPosition
" which will automatically scroll to a specified position, you could be talking about manual scrolling and you could be talking about flinging. For the sake of prosperity, I will attempt to answer all of these issues now.
1. Automatic smooth scrolling.
Inside your layout manager, you need to implement the smoothScrollToPosition
method:
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, State state, int position)
{
// A good idea would be to create this instance in some initialization method, and just set the target position in this method.
LinearSmoothScroller smoothScroller = new LinearSmoothScroller(getContext())
{
@Override
public PointF computeScrollVectorForPosition(int targetPosition)
{
int yDelta = calculateCurrentDistanceToPosition(targetPosition);
return new PointF(0, yDelta);
}
// This is the important method. This code will return the amount of time it takes to scroll 1 pixel.
// This code will request X milliseconds for every Y DP units.
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics)
{
return X / TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, Y, displayMetrics);
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
In this example, I use a helper method named "calculateCurrentDistanceToPosition". This can be a bit tricky, since it involves keeping track of your current scroll position, and calculating the scroll position of a given y position. You can find an example of how to keep track of the recycler's scroll y here.
Calculating the scroll y of a given position is really dependent on what your recycler is displaying. Assuming all your items are the same height, you can calculate this by performing the following calculation:
targetScrollY = targetPosition * itemHeight
Then, to calculate the distance you need to scroll, simply subtract the current scroll y with the target scroll y:
private int calculateCurrentDistanceToPosition(int targetPosition) {
int targetScrollY = targetPosition * itemHeight;
return targetScrollY - currentScrollY;
}
2. Slowing down manual scrolling.
Once again, you need to edit your layout manager, this time - the scrollVerticallyBy
method:
@Override
public int scrollVerticallyBy(int delta, Recycler recycler, State state)
{
// write your limiting logic here to prevent the delta from exceeding the limits of your list.
int prevDelta = delta;
if (getScrollState() == SCROLL_STATE_DRAGGING)
delta = (int)(delta > 0 ? Math.max(delta * MANUAL_SCROLL_SLOW_RATIO, 1) : Math.min(delta * MANUAL_SCROLL_SLOW_RATIO, -1));
// MANUAL_SCROLL_SLOW_RATIO is between 0 (no manual scrolling) to 1 (normal speed) or more (faster speed).
// write your scrolling logic code here whereby you move each view by the given delta
if (getScrollState() == SCROLL_STATE_DRAGGING)
delta = prevDelta;
return delta;
}
Edit: In the above method, I call "getScrollState()
". This is a method of RecyclerView
. In this implementation, my custom LayoutManager
is a nested class of my custom RecyclerView
. If this doesn't work for you, you can try to grab the scroll state via some interface pattern.
3. Slow down the fling speed
Here you want to scale down the fling velocity. You will need to override the fling
method inside your RecyclerView subclass:
@Override
public boolean fling(int velocityX, int velocityY)
{
velocityY *= FLING_SCALE_DOWN_FACTOR; // (between 0 for no fling, and 1 for normal fling, or more for faster fling).
return super.fling(velocityX, velocityY);
}
It's difficult for me to provide a more tailored solution, since you didn't post any of your code, or provide much information about your setup, but I hope this covers most bases and will help you find the best solution for you.
Android RecyclerView with gridlayout smoothScrollTo() speed
My simple working solution currently is still implementing a timer then working with it.
final CountDownTimer scrollUp_timer = new CountDownTimer(50000, 30) {
@Override
public void onTick(long millisUntilFinished) {
if (layoutManager != null && layoutManager.findFirstVisibleItemPosition() != 0) searchRecyclerView.smoothScrollToPosition(layoutManager.findFirstVisibleItemPosition()-1);
}
@Override
public void onFinish() {
try{
}catch(Exception e){
// log
}
}
};
scrollUp.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View view, DragEvent dragEvent) {
layoutManager = ((GridLayoutManager)searchRecyclerView.getLayoutManager());
int action = dragEvent.getAction();
if (action == DragEvent.ACTION_DRAG_ENTERED) {
scrollUp_timer.start();
} else if (action == DragEvent.ACTION_DRAG_EXITED) {
searchRecyclerView.scrollBy(0,0);
scrollUp_timer.cancel();
}
return true;
}
});
Related Topics
Firebase Ontokenrefresh() Is Not Called
Android: Setselection Having No Effect on Spinner
Error 12501 Authenticating with Google Sign-In
What Is a Maximum Size of SQLite Database on Android
Listen to Own Application Uninstall Event on Android
How to Disable Status Bar Click and Pull Down in Android
Using Camera in the Android Emulator
Run Task Before Compilation Using Android Gradle Plugin
How to Open My Existing Eclipse Projects in Android Studio
Programmatically Add View One Below Other in Relative Layout
Pagination Not Work for the Recyclerview Within Nestedscrollview
Continuous Speech Recognition Android
Android Camera Android.Hardware.Camera Deprecated
Gmail 5.0 App Fails with "Permission Denied for the Attachment" When It Receives Action_Send Intent
Android -- How to Position View Off-Screen
Android Emulator Issues in New Versions - the Emulator Process Has Terminated