RecycleView: how to go to a row without scrolling - android

If the recyclerview has a list of items and I want to go to a specific row immediately when user enters the UI, so I don't want the user to see it scroll to reach that row. Is it achievable?
Thanks.

You can use method scrollToPositionWithOffset (int position, int offset)
Scroll to the specified adapter position with the given offset from
resolved layout start.
See documentation
Example:
//Scroll to item position 2 with offset 0
RECYCLERVIEW_LAYOUT_MANAGER.scrollToPositionWithOffset(2, 0);
Hope this will help~

I would say it is impossible.
RecyclerView#scrollToPosition causes sort of animation because it does not know the height of all rows initially. Not all items are loaded immediatly but one by one as you scroll down the list.

I use ListView and I solved the issue by calling setSelection(position)

Related

Android RecyclerView best practice for displaying items

I have a reyclerview in which every time I add an item I add it at index 0, Usually when you add an item a given index you can do it like so
mAdapter.add(0, item)
mAdapter.notifyItemChanged(0)
the problem is the item will be added to index 0 but the user will have to scroll to view it, of course, there is a solution which is by simply doing the following
messageAdapter.add(0, item)
messageAdapter.notifyDataSetChanged()
the problem here is that by calling "notifyDataSetChanged()" the item will appear all of sudden inside the list which I don't like I want to have a nice and smooth animation for when the item is added, another solution is to manually smooth scroll the recyclerView whenever an item is added using our first code, this solution is the best but it has some problems.
when the user is viewing item at index 999 and a new item is added the view will be scrolled to index 0 which can be kind of annoying for the user, the solution is simple for this problem, we can check if the item at index 0 is visible if it is, then scroll to index 0, this is the perfect solution for my problem.
So my question is, is there any other way to implement the functionality that I want to achieve without having to do that work? I would like to know what the simplest way is, thank you in advance!
Try using diff util it will be better for performance for updating recyclerview
https://blog.mindorks.com/the-powerful-tool-diff-util-in-recyclerview-android-tutorial

Infinite List in Android

I want to create an infinite list , when i scroll to the end of list , my list will show first item, second item ... at the end() . Such as :
item[0]
........
item[last]
item[0]
item[1]
The first thing comes to my mind is that I will double the list so it can show like I wished.
Unfortunately , it's a bad idea because size of my list will grow more and more , and loading a big list is not good for performance(obviously).
May you guys show me other solutions to handle this case ? Thank you very much .
Using RecyclerView, you can achieve what you want in few steps. The idea is to set adapter's item count to infinity, and place your first item to the middle of infinity.
In your Adapter override getItemCount() method like this.
#Override
public int getItemCount() {
return Integer.MAX_VALUE;// Not the infinity, but I'm not sure someone will scroll about 2 million items and find out that's a cheat
}
Then in the class where you use the RecyclerView, get LayoutManager and set starting position to the middle of adapter itemCount.
LinearLayoutManager layoutManager = getLayoutManager();
int pos = (Integer.MAX_VALUE / 2); //Voila, you are in the middle of infinity
layoutManager.scrollToPosition(pos);
yourAdapter.setLayoutManager(layoutManager);
By doing this you are able to scroll your list in any direction up to about 2 000 000 scrolls, without container size increasing and any performance issues.
You need to update your list when user reach bottom of the page.
You can keep track end of the page in on-scroll Listener.
Once user reach bottom of the or about to reach bottom of the page just double your list or extend it as per your requirement.
Extend or double your list is required because we need to store or display the data of each item in each row.
And Same thing happen in pagination concept.
Clearly understood we are not extending list unnecessary, we are extending when we really need.
You can visit this link for Endless Scrolling with AdapterViews and RecyclerView.
use onScrollListener() and when got to the end , use LIST.size()+VisibleItems (items from end of list that are visible) and put them first on array and renew your adapter data
sorry for very briefing Explanation !!!

Dynamically adding items to top of listview

Is it possible to insert a ListView item to the top of the list, with the position of the most recent item going at the top? I am aware of other methods of achieving this, such as items.add(0, item);, getItem(getCount() - position - 1); as well as using listView.smoothScrollToPosition(0); within a runnble(), but the results are as shows in this image, where the numbers represent an int position index. New items added to the list are placed at the bottom, pushing all previous items upward.
I would like a result like this?
Thanks in advance.
I solved my own problem! Basically I used the method which involves placing each item in the list at index 0, items.add(0, layer); which visually, does indeed stacks the elements in my list, but at the cost of reversing the position index. All I needed to do was modify the recieved int position index so that it corresponds to the positions of the reversed list.
You can't normally do this with listview. Try bottom sheet which is explained here.

How to programmatically snap to position on Recycler view with LinearSnapHelper

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()
More general solution:
First scroll RecyclerView to make target item visible.
Than, take the object of target View and use SnapHelper to determine
distance for the final snap.
Finally scroll to target position.
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]);
}
}
});
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 :)
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!

Android - Reverse listview as message display

I've got a little question for my Android App.
I searched for a long time but found nothing about my problem.
Scenario : I've to display a revert listview (as Facebook Messenger).
And when the user scrolls to the top, load more messages.
Problem : After notifiyDataAsChanged() call, the scroll is not the same!
I want to conserve exactly the same position as before loading.
I tried that code :
// save index and top position
int index = list.getFirstVisiblePosition()+result.size();
View v = list.getChildAt(index);
int top = (v == null) ? 0 : v.getTop();
// ...
// restore
list.setSelectionFromTop(index, top);
But the scroll is not exactly the same after loading.
Have you got an idea ?
I think you should look into using TranscriptMode and StackFromBottom with your listview:
android:stackFromBottom="true"
android:transcriptMode="normal"
By setting the transcript mode to normal it will scroll to the bottom only if the last item was already in view. That way your users can view the previous list view items without interruption when you call notifydatasetchanged.
do like this:
Collections.reverse(YourList); // ADD THIS LINE TO REVERSE ORDER!
YourList.notifyDataSetChanged;
I fixed this by using the same code as you included but I update the index variable by the number of items I add to the adapter before restoring the position. Seems to do the trick.
For Kotlin is more easy just
myList.reverse()

Categories

Resources