My recyclerview should open the first item closed. To this end, I wrote these lines.
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.scrollToPosition(1);
paletteRecyclerView.setLayoutManager(llm);
I want to check if it is possible to scroll to position 1 fully. If my recyclerview is small I must open it without closing the first item. How can I check it?
I assume that you want to know if there are items to scroll in RecyclerView. So you can check as below after setting the adapter to the recyclerView.
recyclerView.post(new Runnable() {
#Override
public void run() {
int recyclerViewheight = recyclerView.getHeight();
int totalChildViewsHeight = recyclerView.computeVerticalScrollRange();
if (recyclerViewheight > totalChildViewsHeight) {
//there is no scroll (there are no more items to scroll)
} else {
//there is scroll (there are items to scroll)
}
}
});
Try with below code...
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(llm);
RecyclerView.Adapter adapter = new YourAdapter();
recyclerView.setAdapter(adapter);
recyclerView.scrollToPosition(position);
Related
i have a recyclerview with hidden items under condition and it works great but when i scroll the recyclerview it keeps scrolling an empty page after i scroll all the data included here is my code
adapter
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.id.setText(mData.get(position).getId());
holder.date.setText(mData.get(position).getDate());
holder.itemName.setText(mData.get(position).getItemName());
holder.price.setText(mData.get(position).getPrice());
if (holder.id.getText().toString().equals("")){
holder.itemView.setVisibility(View.GONE);}
else{
holder.itemView.setVisibility(View.VISIBLE);
}
in recyclerview activity
mData.add(new items(num,itemName,price,date,row));
adapter = new Adapter(mData,recyclerViewItems.this);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setReverseLayout(false);
linearLayoutManager.setStackFromEnd(false);
recyclerView.setAdapter(adapter);
i want the recyclerview to stop scrolling at the last visible item and i dont know how to do it
please help me
thank you in advance
I have a recyclerview with several items. I need to show the items starting from bottom i.e. first item should be displayed at bottom and after scrolling from bottom to top, further items will get displayed.
For this what I tried is,
linearlayoutManager.setStackFromEnd(true);
This helped to start the items from bottom. But when there are several items, more than the size to fit into the screen at the same time then the first item goes moving at the top as the item count increases.
I also tried with
linearlayoutManager.scrollToPosition(0);
This didn't change anything.
Here is an image showing what I am looking for.
There are few more items in the list above which are still not visible.
Here how it looks When these items are scrolled,
.
I have checked view hierarchy of this view in the image which only shows a recyclerview and the items within it. And the recyclerview's height is match_parent i.e. the top space with no items showing another view underneath of the recyclerview which is a google map.
I just need to know how I can achieve this feature of the recyclerview without using more extra views.
Any help would be greatly appreciated..!!
Try to init your Linear layout as follow
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, true);
The third boolean indicates that it should reverse the items or not.
But remember that your datas should be sorted from newest to oldest also.
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true);
linearLayoutManager.setStackFromEnd(true);
linearLayoutManager.setReverseLayout(true);
Then once your data is populated
adapter.notifyDataSetChanged();
recyclerView.post(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(0);
}
});
Try using a reversed LinearLayoutManager:
LinearLayoutManager linearlayoutManager = new LinearLayoutManager(context, VERTICAL, true);
write this line in xml to start list from bottom
android:stackFromBottom="true"
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stackFromBottom="true">
</android.support.v7.widget.RecyclerView>
and second thing reverse your array list before add in adapter
Add these attributes to your recyclerview (XML)
android:paddingTop="500dp"
android:clipToPadding="false"
You can also set it in the code like this:
recyclerView.setPadding(0, 500, 0, 0);
recyclerView.setClipToPadding(false);
This is for different screen sizes
int height = recyclerView.getHeight()
recyclerView.setPadding(0, height - 200, 0, 0);
recyclerView.setClipToPadding(false);
If you don't know how to get screen width, height and convert dp to px
so here are the links: How to get screen width and height and Converting pixels to dp
Seems like what you want is to have a separate view type in your recycler adapter that doesn't show anything but is the height of the map. This would allow you to 'scroll up' from the bottom where the list starts and continue seeing different views.
A simple example:
public class ScreenBottomRecyclerAdapter extends RecyclerView.Adapter {
final int VIEW_TYPE_MAP = 0;
final int VIEW_TYPE_ROW = 1;
#Override
public int getItemCount() {
return dataset.length + 1;
}
#Override
public int getItemViewType(int position) {
if (position == 0) {
return VIEW_TYPE_MAP;
} else {
return VIEW_TYPE_ROW;
}
}
#Override
public RecyclerView.ViewHolder createViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_MAP: return new ViewHolder(null); // This is an empty recycler row so you can see and interact with the map, it will need to be the height of the map so you'll probably want to make a new view type that the same height but doesn't show anything and doesn't intercept touches
case VIEW_TYPE_ROW: return new RowViewHolder(someInflatedView); // This will be the rows you are already creating
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case VIEW_TYPE_ROW: holder.update(position - 1) // Do your normal update here, but remember that your data will be off by 1 for the map view row in the recycler
}
}
}
Use below code to reverse list:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), RecyclerView.VERTICAL, false);
Important: Set layout manager which have property reverse layout to true
layoutManager.setReverseLayout(true);
RecyclerView.setLayoutManager(layoutManager);
This code will display reverse list which you may have assigned to RecyclerView
I use smoothScrollToPosition to scroll RecyclerView. It does scroll every time a new entry is inserted; but to the top, not to the bottom, which is the direction i want.
list_chat = (RecyclerView) findViewById(R.id.list_chat);
//Set up Layout Manager
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
list_chat.setLayoutManager(linearLayoutManager);
//set adapter
list_chat.setAdapter(adapter);
//set scroll
list_chat.post(new Runnable() {
#Override
public void run() {
list_chat.smoothScrollToPosition(adapter.getItemCount());
}
});
The adapter is from Firebase
adapter = new FirebaseRecyclerAdapter<ChatItem, ChatRecylerViewHolder>(ChatItem.class,R.layout.chat_item
,ChatRecylerViewHolder.class,queryChat ) {
#Override
protected void populateViewHolder(ChatRecylerViewHolder viewHolder, ChatItem model, int position) {
viewHolder.tvAuthorChat.setText(model.chatAuthor);
viewHolder.tvContentChat.setText(model.chatContent);
}
};
You do notice you are using linearLayoutManager.setStackFromEnd(true); this mean you first position is at the bottom. I suggest you a better option.
RecycleView didn't work the way listView work, you can scroll it with your layout manager something like this
linearLayoutManager.scrollToPositionWithOffset(position,offset);
Which position is the position you want to scroll to, offset is the offset within the current position. You could just use with one parameter as well.
linearLayoutManager.scrollToPosition(position);
Ok. I found the answer.
First, the old problem with my question: i thought list_chat.post is called whenever an item is inserted (turn out that is wrong). The reason for it keeps scrolling top is linearLayoutManager.setStackFromEnd(true);
Thus, the question comes down to Where to call the scrolling ?
The answer is : Since adapter manages data, it makes sense to guess that adapter will notify the insertion.
Here is the code
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
list_chat.smoothScrollToPosition(adapter.getItemCount());
}
});
I'm using a FirebaseIndexRecyclerAdapter as described on https://github.com/firebase/FirebaseUI-Android/tree/master/database. But my list has many items and I want to only load a few items at first and then lazy load the rest when the user scrolls up.
My first thought was that I could use mKeyRef.limitToLast(5) but then updating this requires recreating the Adapter, right?
How do I achieve this lazy-loading mechanic?
RecyclerView recycler = (RecyclerView) findViewById(R.id.messages_recycler);
recycler.setHasFixedSize(true);
recycler.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new FirebaseIndexRecyclerAdapter<Chat, ChatHolder>(
Chat.class,
android.R.layout.two_line_list_item,
ChatHolder.class, mIndexRef,
mDataRef) {
#Override
public void populateViewHolder(ChatHolder chatMessageViewHolder, Chat chatMessage, int position) {
chatMessageViewHolder.setName(chatMessage.getName());
chatMessageViewHolder.setText(chatMessage.getText());
}
};
recycler.setAdapter(mAdapter);
I have converted the chat layout from listView to RecyclerView.
Now m facing some problem, When new messages arrive then it not showing automatically, I have to manually scroll to that messages.
Earlier in ListView it working.
I have used set setStackFormEnd in recylerView.
I want feature like whatsapp has like
if new message arrives and you are able to view last message then it will show that messages but
if you scrolling the messages then it doesn't change the position.
layoutManager.setStackFromEnd(true);
messagesView.setLayoutManager(layoutManager);
messagesView.setItemAnimator(new DefaultItemAnimator());
messagesView.addOnScrollListener(mOnScrollListener);
Sample on Create Code Code
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
final Button addButton = (Button) findViewById(R.id.button_is_reverse);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new DividerDecoration(this));
adapter = new SampleAdapter(items);
recyclerView.setAdapter(adapter);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
items.add("Items" +items.size());
adapter.notifyItemInserted(items.size());
}
});
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true)
yourRecyclerView.setLayoutManager(layoutManager);
Scroll the recyclerview to last position
messagesView.scrollToPosition(messages.size()-1);
Where messages is your list of messages.
Use these line after you send/receive message event.
mRecyclerView.postDelayed(new Runnable() {
#Override
public void run() {
mRecyclerView.smoothScrollToPosition(mRecyclerView.getAdapter().getItemCount());
}
}, 100);