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();
Related
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
I need to be able to programmatically dismiss an item inside a RecyclerView without the user actually swiping (instead I want to dismiss the item when they tap a button in the card). A lot of libraries I've seen only seem to support actual swipes.
I've tried using an existing library and just simulate a MotionEvent by creating a swipe on my own programmatically, but this interferes with another horizontal-swipe listener, so I'm wondering how else this could be done, ideally for a RecyclerView but if anyone knows how to for a ListView instead I can try to adapt that.
I've looked at this library as well as others for inspiration but I can't figure out how to trigger the swipes programmatically instead.
Use a ListView or RecyclerView with custom adapter, and call notifyDataSetChanged after removing an item from the datalist:
private void removeListItem(View rowView, final int position) {
Animation anim = AnimationUtils.loadAnimation(this,
android.R.anim.slide_out_right);
anim.setDuration(500);
rowView.startAnimation(anim);
new Handler().postDelayed(new Runnable() {
public void run() {
values.remove(position); //Remove the current content from the array
adapter.notifyDataSetChanged(); //Refresh list
}
}, anim.getDuration());
}
Use one of the libraries that offer the swipe to dissmis funcionality ad extract the animation part, if im not mistaken its at the action_up at the onTouch(). Then call it from your onClick of the button.
As mentioned here, Android's GridView.scrollTo() doesn't work. The method the solution mentioned, setSelectedPosition, doesn't seem to exist in GridView
smoothScrollToPosition does work, but I really don't want the animation.
For context, I have a CursorAdapter-backed GridView, and I want the view to "reset", i.e. scroll to the top, when I change the cursor.
I've been using setSelection(int position) for this, and it seems to be working just fine. To scroll to the top, just use 0 for position.
From the docs:
If in touch mode, the item will not be selected but it will still be positioned appropriately.
Edit:
Added code to post setSelection as a Runnable:
albumsView.post(new Runnable() {
#Override
public void run() {
albumsView.setSelection(0);
}
});
I have found that in order to reliably use gridView.setSelection(index), I have to first call gridView.setAdapter() (even if the adapter has already been set and has not changed). Like so:
gridView.setAdapter(gridAdapter);
gridView.setSelection(index);
I have a ListView that potentially can have hundreds of entries. When a selection is made I've been using a smoothScrollToPosition, thusly:
if (lv != null) { //Are we created yet?
lv.post(new Runnable() {
public void run() {
lv.smoothScrollToPosition(k);
}
});
}
but my users have told me they don't like the scrolling animation and would prefer to just instantly go there. So I replaced my smooth scroll with
lv.setSelection(k);
... and now it does nothing at all. FWIW this is all happening right after a notifyDatasetChanged
In searching for a solution I came across this discussion on http://code.google.com/p/android/issues/detail?id=6741 which implies this is a known problem. Is there a workaround or am I just doing this wrong?
Thanks in advance.
The documentation of setSelection says that it only scrolls to the selected position when the ListView is in touch mode. Maybe ListView is no more in touch mode once the data set has changed or maybe setSelection is simply forgotten for the next UI update cycle.
I guess you could try a workaround by calling setSelection with a delay. You could use the postDelayed method with a delay of 100 milliseconds for example. Or you could extend ListView and override layoutChildren or something related that probably gets called when the data set changes in order to re-calculate the list view item measurements. At that point it should be safe to call setSelection and you don't need to rely on guesstimating a delay.
I'm using a ListView with an ArrayAdapter, and code executing after ListView.setAdapter(ArrayAdapter,...) is seeing ListView.getChildCount()==0.
Is there a way t wait for the UI thread to finish filling the ListView before continuing?
Thanks in advance,
Lenny
ListView.getChildCount() is inherited from ViewGroup and is not related to the items managed by the adapter but the child views managed by the ListView.
To get the number of items displayed by the ListView use getCount() which returns the number of items managed by the adapter.
I had a similar problem that I solved creating a thread that has while loops that can only go forward after the list is loaded.
new Thread(new Runnable() {
public void run() {
while(listView.getCount() == 0) ;
}
}).start();
This approach can be done cuz I garantee that at this point there is something in the list. Be carefull using this approach. It is not the best one but it was the one that I found.