Reputation: 7853
I have implemented a horizontal recyclerView with LinearSnapHelper, to implement a UI input that selects a particular configuration. Kinda like the old school number picker/selector or spinner. The item in the center is the selected position.
it works fine and all, but here's the problem. On initial start up, I need to programmatically set the position of the recycler view such that the selected item (the index of which was loaded from disk) is position in the center.
.scrollToPosition()
wont work becuase it places the selected item in the begining.
now I know I can do all the math and calculate the x coordinate and manually set it, but thats a lot of redundant work because LinearSnapHelper is already doing this, and I feel like there should be a way to just reuse that logic, but with actually initiating a fling.
I need something like LinearSnapHelper.snapToPosition()
Upvotes: 20
Views: 12963
Reputation: 1
greetRecycler.scrollToPosition(targetPosition)
greetRecycler.post {
val view = layoutManager.findViewByPosition(targetPosition)
if (view == null) {
Log.e("SANJAY", "Cant find target View for initial Snap")
return@post
}
val snapDistance = snapHelper.calculateDistanceToFinalSnap(layoutManager, view)
snapDistance?.let {
if (it[0] != 0 || it[1] != 0) {
greetRecycler.scrollBy(it[0], it[1])
}
}
}
Upvotes: 0
Reputation: 397
More general solution:
NOTE: This works only because programmatically you are scrolling at the exact position & covering the missing distance by exact value using scrollBy
instead of doing smooth scrolling
Code snippet:
mRecyclerView.scrollToPosition(selectedPosition);
mRecyclerView.post(() -> {
View view = mLayoutManager.findViewByPosition(selectedPosition);
if (view == null) {
Log.e(WingPickerView.class.getSimpleName(), "Cant find target View for initial Snap");
return;
}
int[] snapDistance = mSnapHelper.calculateDistanceToFinalSnap(mLayoutManager, view);
if (snapDistance[0] != 0 || snapDistance[1] != 0) {
mRecyclerView.scrollBy(snapDistance[0], snapDistance[1]);
}
}
});
Upvotes: 38
Reputation: 37
I have a recyclerView
which I have added padding
at the left
and right
with dummy views in the adapter. So that the first "actual" item can be snapped to.
I couldn't get smoothScrollToPosition(0)
to work though for the initial snap. I used the following
recycler.scrollBy(snapHelper.calculateDistanceToFinalSnap(binding.recycler.getLayoutManager(), recycler.getChildAt(1))[0], 0);
Isn't the nicest looking way, but seems to work!
Upvotes: -2
Reputation: 89
Try calling smoothScrollToPosition on the RecyclerView object, and passing the position index (int)
mRecyclerView.smoothScrollToPosition(position);
Worked for me with a LinearLayoutManager and LinearSnapHelper. It animates the initial scroll, but at least snaps the item in position.
This is my first post on the stack, hope it helps :)
Upvotes: 7