I have a RecyclerView with horizontal items. These items have fix 150dp height and 100dp width.
When the Fragment is loaded, than I set default items to this view.
After that, I make a Room getImages() call, when the result arrive than I rebuild this RecyclerView.
As you see in the GIF :
Default images loaded (2 with play button, 3 with pro image)
Add getImages() result
The result is inserted before the 1st default item
Play button cards have fix id actually ("-1") and pro have another fix ("0") and every image item have unique id.
The new item is added before the first item, and the user don't see it. The RecyclerView won't scroll to first item.
There is any solution push the first item to right when a new one added to 1st place??
I tried the smoothScrollToPosition but it won't work after submitList() and maybe where is any better solution.
All you have to do is use Recyclerview's smooth scroller
smoothScroller = new LinearSmoothScroller(this) {
#Override
protected int getHorizontalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_ANY;
}
};
then when you want to scroll to first position of recyclerview
smoothScroller.setTargetPosition(0);
horizontalLayoutManagaer.startSmoothScroll(smoothScroller);
Try to use scrollToPosition(0) instead.
If that won't work, try whether adding a small delay is fixing it, like so:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
recyclerView.scrollToPosition(position); // Or maybe `smoothScrollToPosition()`
}
}, 300); // Try a delay of 200 or 300 ms
Related
Scenario:
my adapter supports two different view types: A & B
the adapter is notified about 100 items of type A - everything is rendered correctly
the adapter is notified about one item of type B insertion using
notifyItemRangeInserted at position 0 - this item is "invisible"
by default and in order to see it I have to manually scroll up.
How can I get this first item of type B "automatically" visible?
You can use this line of code after notify item of type B:
yourRecyclerView.smoothScrollToPosition(0);
using https://stackoverflow.com/a/54899984/8144663 only wont resolve your issue.
You will need to call smoothScrollToPosition() in the next frame like,
recyclerview.post(new Runnable() {
#Override
public void run() {
recycleview.smoothScrollToPosition(n);
}
});
I have a listview with 150+ items, I need to make one visible from code. I currently use smoothscrolltoposition but when the desired item is far away from the current visible item it takes several seconds to arrive.
Is there anyway to simply get rid of the smooth scrolling and simply make the item visible directly?
Thanks,
Ignacio
You can use postdelayed for smooth scroll
listview.postDelayed(new Runnable() {
#Override
public void run() {
// smoothscrolltoposition
}
}, 100);
After several testing and reading the thread suggested by audi , I got this solution:
Strangely, the trick is in reassign the adapter to the listview, not even it is needed to recreate it, just reassign.
listView.Adapter = adapter;
listView.FastScrollEnabled = true;
listView.SetSelection(index);
adapter.NotifyDataSetChanged();
I have a RecyclerView with its RecyclerView.Adapter and view holder. I am trying to delete an item from list, code as follows inside onClick() on delete button in the ViewHolder
int position = getAdapterPosition();
if(position > -1)
{
Place place = placeList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount());
}
Despite removing the view and doing the animation (list also gets affected), the old view (or lower one) still exist or drawn again.
For example, if the list starts with size = 5, then i try to remove index 4, he remove 4, then still draw 5 views.
EDIT
If i remove notifyItemRangeChanged() then it does that bug only if i do the following
1- click on delete
2- click button very quickly that takes me to new view
3- going back to the list where i can delete
4- start deleting, and bug happens. 1 item still remain even though the List size = 0 (getItemCount is called with 0).
If i only call NotifyDataSetChanged(), then it removes item, but view just stays there !!
Any help or suggestion is appreciated.
Thanks.
EDIT complete class LINK
Try this:
placeList.remove(position);
notifyItemRemoved(position);
use below code it will solve your problem.
holder.deleteImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(list.size()!=0){
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,list.size());
}
}
});
I've had the same problem, notifyItemRangeChanged() call didn't help while notifyDataSetChanged() did (though stopped the animation). But I am using the ItemTouchHelper on the RecyclerView (to allow for moving items around), and it became obvious that this class was causing the trouble.
The only difference in my case is that to reproduce this overlap-after-delete bug, user has to long press on an item while deleting it.
After I modified the overriden isLongPressDragEnabled() method of ItemTouchHelper.Callback to return false instead of true, the issue was solved.
lastImages.remove(position); (lastImages equals your array list)
newContentAdapter.notifyDataSetChanged();
it is works. You have to remove it in your array not item. then notify adapter. Thats all
for me notifyItemRemoved and notifyDataSetChanged doesnt work. I tried everything , only solution that worked for me is calling or reloading recycler view inside onSwiped method!
you don't have to create new reference of place list.that need to declared as array list. you can't add or remove a object from list. you can do that only with arraylist.
change this lines
private List<Place> placeList;
Place place = placeList.remove(position);
to
private ArrayList<Place> placeList;
// other codes
placeList.remove(position);
// print placeList to confirm
notifyItemRemoved(position);
I had this issue
when I'm using notifyDataSetChanged() it works fine but I wanted the animation so I used notifyItemRemoved(position) for animation then I used notifyDataSetChanged() but I delayed the interval between those functions
I made extension for it you can use it on any RecylcerView
fun RecyclerView.removeItem(position: Int){
adapter?.notifyItemRemoved(position)
handler.postDelayed({
adapter?.notifyDataSetChanged()
},300)
}
You need to update you adapter;
Create method in Adapter class where you will be put your data.
For example : setData(List<Place> data);
When last item in list you need to write: adapter.setData(null);
I had the same problem. Just set list = null. It's all.
I am using endless scroller with recylerview and it is loading products at bottom but always on load more call my page starts from top not from bottom.
Am I doing something wrong? I am using https://gist.github.com/ssinss/e06f12ef66c51252563e as an endless scroller and my code in activity is:
recyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
#Override
public void onLoadMore(int current_page) {
String load_more_url = url + "&page=" + String.valueOf(current_page);
bottamProgressBar.setVisibility(View.VISIBLE);
productVolleyLoader = new ProductVolleyLoader(getApplicationContext(), load_more_url,productList,
myAdapter,bottamProgressBar, productRecyclerView);
productVolleyLoader.volleyLoader();
}
});
Very Sorry for this silly question. Actually I was setting adapter in volley loader instead of there I have to set adapter in onCreate method and in volley loader I just have to use notifyDataSetChanged();.
After that scrolling is working fine.
At the end of the "onLoad" method, call:
mRecyclerView.smoothScrollToPosition(lastPosition);
Getting the last position from the view with mRecyclerView.getChildCount() or something like that if each item is a child inside the RecyclerView. Save it to a variable on the begining, so you'll have the last position before the load and scroll there on the end of the load.
You are adding the new values in the old list in load more. So every time its a new list.
You will have to programmatically scroll to the last position of the view.
When you are calling for load more, save the position and when list loads, scroll to that position programmatically.
I am writing an android app where I am using a grid view to display some items. I want to give users a configurable view where they can change the no of columns on the activity by clicking floating action button. I am changing the column no using
gridView.setNumColumns(selectedColumnNo);
This is working fine But the problem is if a user changes no of column after some scrolling the First Visible Position is set to the first item of the array list, so the user has to scroll the view again. Can someone please tell me where I am doing wrong. Or Is this the proper way to do this or should I use a different approach.
A code snippets will be helpful
Thanks.
Update::
currently I am using the bellow snippets
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int firstPosition = gv.getFirstVisiblePosition();
if(gv.getNumColumns()==2)
{
gv.setNumColumns(1);
gv.setSelection(firstPosition);
}
else {
gv.setNumColumns(2);
gv.setSelection(firstPosition);
}
}
});
Now the problem is on every 4th switch grid view is showing the first element of the arraylist
Right before you call setNumColumns(), save the GridView's first visible position:
int firstPosition = gridView.getFirstVisiblePosition();
Then, after you change the number of columns, pass that integer to setSelection():
gridView.setSelection(firstPosition);
"Selection", counter-intuitively, is not the same thing as "activation". It will ensure that the view is on-screen, but not visibly affect it in any other way.