How to Use Recyclerview.Scrolltoposition() to Move the Position to the Top of Current View

Scroll RecyclerView to show selected item on top

If you are using the LinearLayoutManager or Staggered GridLayoutManager, they each have a scrollToPositionWithOffset method that takes both the position and also the offset of the start of the item from the start of the RecyclerView, which seems like it would accomplish what you need (setting the offset to 0 should align with the top).

For instance:

//Scroll item 2 to 20 pixels from the top
linearLayoutManager.scrollToPositionWithOffset(2, 20);

How to focus/scroll to a specific item in recyclerView by fetching item position

Add public function into your adapter.

public class EventsAdapter extends RecyclerView.Adapter<EventsAdapter.ViewHolder> {
...
public int getItemPosition(String eventId) {
for (int i = 0; i < eventsDataModels.size(); i++) {
if (eventsDataModels.get(i).getEventID().equals(eventId)) {
return i;
}
}
return -1;
}

Activity:

private void scrollToPosition() {
String eventId = "someId";
int position = adapter.getItemPosition(eventId);
if (position >= 0) {
recycler.scrollToPosition(position);
}
}

RecyclerView scroll to position when a new item is added

If want to add the data to the bottom of the list you need to use setStackFromEnd() in RecyclerView Layout Manager.

But first, you need to fix your Adapter. You must not pass your RecylerView to your Adapter. So the following code is wrong:

...
// This is wrong!!
adapter = new RecyclerViewAdapter(data, recyclerView);

recyclerView.setAdapter(adapter);

You need to change your Adapter constructor to only receive the data as its parameter. Something like this:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

private List<Data> mData;

public RecyclerViewAdapter(List<Data> data) {
this.mData = data;
}

...
}

Then you can set the data to always added at the last bottom with the following code:

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);

adapter = new RecyclerViewAdapter(data);
recyclerView.setAdapter(adapter);

To add the new data, you better to make a new method in the adapter. Something like this:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

private List<Data> mData;
...

public void addItem(Data datum) {
mData.add(datum);
notifyItemInserted(mData.size());
}
}

Whenever you have adding a new data, you need to scroll to the bottom with scrollToPosition method. Something like this:

adapter.addItem(newData);
recyclerView.scrollToPosition(adapter.getItemCount() - 1);

Remember that you need to override getItemCount() in your Adapter. It should be something like this:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

private List<Data> mData;
public RecyclerViewAdapter(List<Data> data) {
this.mData = data;
}

// Return the total count of items
@Override
public int getItemCount() {
return mData.size();
}

...
}

Please be aware that I'm using a Data pojo as a sample here. You need to change it according to your data type.

RecyclerView - How to smooth scroll to top of item on a certain position?

RecyclerView is designed to be extensible, so there is no need to subclass the LayoutManager (as droidev suggested) just to perform the scrolling.

Instead, just create a SmoothScroller with the preference SNAP_TO_START:

RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) {
@Override protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
};

Now you set the position where you want to scroll to:

smoothScroller.setTargetPosition(position);

and pass that SmoothScroller to the LayoutManager:

layoutManager.startSmoothScroll(smoothScroller);

Recycler view scroll to specific position

Try this:

myRecyclerview.scrollToPosition(position);

if not works in some cases(Keyboard opening etc.), try using delay.

new Handler().postDelayed(new Runnable() {
@Override
public void run() {
myRecyclerview.scrollToPosition(position);
}
}, 200);

scrollToPosition() when updating RecyclerView in a fragment

  1. First of all don't use ListAdapter RecyclerView has a more optimized adapter here

  2. in your adapter provide a function that overrides the item list and there is where you notify the data change

  3. Use smoothScrollToPosition(lastVisiblePosition) to scroll to the last visible position where lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()

  4. Update lastVisiblePosition before you push new items to the adapter notifyDatasetChanged()

Step 2

fun updateList(newItems:List<Movie>) {
moviesList.addAll(newItems)
lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()
notifyDataSetChanged()
}

from your view when you call adapter.updateList(newItems) just call recyclerView.smoothScrollToPosition(adapter.lastVisiblePosition)

how to let item scroll to top of the Recycleview when using LinelayoutManager.scrollToPositionWithOffset?first time not effect

get linearLayoutManager from your recyclerView List like this:

((LinearLayoutManager) mList.getLayoutManager()).scrollToPositionWithOffset(mPositionToScroll, 0);

Recyclerview: Scroll down

I,m assuming you're using a custom adapter with some kind of RecyclerView or so.
Simply create static boolean variable that helps hold true when the bottom is reached in your adapter like below, i'm assuming recyclerView in this case.

public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {

public static boolean bottomReached = false;

@Override //Make sure it happens on bindViewHolder or related...
public void onBindViewHolder(final ViewHolder holder, int position) {
if (position == data.size() - 1)
bottomReached = true;
else
bottomReached = false;

}

}

So in your activity, for example chatActivity, we do like below.

public class ChatActivity extends AppCompatActivity{
ChatAdapter chatAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);

chatAdapter = new ChatAdapter(this, messagesDataSample);
}

private void gotNewMessage(){
if(chatAdapter.bottomReached)
recyclerView.scrollToPosition(adapter.getItemCount() - 1);
else
// else is not necessary as you don't want to do anything.
}

}

Hopefully this helps, else pls let me know what goes wrong.

RecyclerView scroll returning to the top of the list when add new items

As you are creating a new adapter each time, the RecyclerView will be always going back to the start position. You have to update the current adapter, and not to create another adapter with the entire list.

You should have a method on your adapter to manage the item list, such as

fun updateList(product: Product) {
myList.add(product.list)
}

And in your else branch you will need to update the list

recyclerView.apply{
(adapter as? ViewHolderAdapter)?.updateList(products)
}


Related Topics



Leave a reply



Submit