Scrolling android gridview blocking userinteraction - android

I have a gridview placed inside scrollview.
When app is launched the 12 items are displayed(page 1) in gridview.
WHen user scrolls and reaches the end of the scroll, next 12 items of next page is fetched via webservice, added to the initial array of items.
the notifydatasetchanged of gridview adapter is called and also the height of gridview is set dynamically.
But the issue is in point #3. This is blocking the user interaction for 1-2 seconds.
Please help.

Have you tried performing the update in a thread?
runOnUiThread(new Runnable() {
public void run() {
//Update the grid view and set height.

Related

RecyclerView - Any way to get how many items are visible on screen before user starts scrolling?

One of my activities contain a RecyclerView.
On launching the activity, I want to know how many times onBindViewHolder() would run before user does any scrolling. Using logging, I checked that it runs almost as many times as the number of items visible on the screen. So essentially I want to know how many items are visible on the screen.
getItemCount() gives the total number of items. This is not what I want.
Is there any other way or method to get only the count of visible items?
I checked this post, but it did not help my case - Get visible items in RecyclerView
To get RecyclerView visible count you can use layoutManager.getChildCount().
But you have to use like this :
layoutManager.postOnAnimation(new Runnable() {
#Override
public void run() {
System.out.println("Visible count " + layoutManager.getChildCount());
}
});

How can I make a scroll view scroll to the bottom?

I have tried this using methods I could find on internet.
My program is a listview containing 3000 webviews (webview inside a cardview).
(I dont think this issue is because webview being a scrollable one)
When I start the activity it is scrolled to bottom, but not the very bottom, just few webviews (around 10) out of 3000 stays below the screen.
I suspect the issue is because, the webview resizes just in milliseconds after it is loadData with a local String.
I have tried,
mainListView.post(new Runnable() {
#Override
public void run() {
// Select the last row so it will scroll into view...
mainListView.setSelection(getCount() - 1);
}
});
android:transcriptMode="alwaysScroll"
android:stackFromBottom="true"
both resulting same.
Try:
myListView.setSelection(myListAdapter.getCount() - 1);
First you get the total count of the item available in your listview, the set the selection to the last item by minus 1, since the setSelection() start from 0.

How to avoid jerk when notifyDataSetChanged method of adapter is called?

I am trying to add pagination in my listView.
I added a method in my custom BaseAdapter which adds next page results at top of list on scroll to first item in list.
public void addEntriesToTop(List<ChatModel> entries) {
// Add entries to the top of the list
this.chatMessages.addAll(0, entries);
notifyDataSetChanged();
}
So if I have to add next page on top of ListView, I am using like this in my activity.
//result contain new items to be added to top of list
adapter.addEntriesToTop(result);
//so that list scroll sets to last visible message to user
final int index = result.size();
listView.post(new Runnable() {
#Override
public void run() {
//go to user's last scroll position
messagesContainer.setSelectionFromTop(index, 0);
}
});
This method is working fine and retains user's last scroll position. But it has a problem, when I call addEntriesToTop() it scrolls the ListView to bottom(because of notifyDataSetChanged() ) and then when I call setSelectionFromTop it scrolls to user's last position. In this transition, there is small jerk.
Please help me to smooth this transition.
Thanks
As ListView is old and now its obselete, now you can use Recyclerview
instead of ListView, here is the link that helps you to convert your
ListView to RecyclerView. RecyclerView have many methods to add your custom animations and also it have not any jerks while adding/removing items.
Replacing ListView with RecyclerView
For Default Animations you can use this link:
RecyclerView Animations – Add & Remove Items

Android: Setting ListView fast scroll based on visible positions

I am trying to set the fast scroll enabled and visible if there are more items in the list than are currently visible. After setting the adapter, the ListView's count is properly increased but the last visible position is not. As a result I am currently posting a Runnable to wait until the ListView has figured out what items are / aren't visible. The code is as follows:
listView.post(new Runnable(){
#Override
public void run() {
if(listView.getLastVisiblePosition() < (listView.getCount() - 1)){
listView.setFastScrollAlwaysVisible(true);
listView.setFastScrollEnabled(true);
}
}
});
This solution works fine, but feels a bit hackish. Is there a way to know when the last visible position is updated without posting the runnable? Thanks in advance!

Only relayout children and not all the tree

I'm trying to recreate ListView (and AbsListView) logic, with view recycling.
I need this but we can say it's only for understand Android logic.
Suppose my children items are the same (same layout), using fixed height RelativeLayout.
During scrolling, I'm reusing ghost children view and set properties for current item.
It's working fine, since I'm using View.offsetTopAndBottom() and invalidate() instead of requesting layout during scroll for optimization.
My problem is updating the children (RelativeLayout).
Depends of item, I want to hide or show ImageView on this item. For that, I'm just using iconImage.setVisibility( GONE ) and iconImage.setVisibility( VISIBLE ).
Since I'm blocking requestLayout, it seems to be setVisibility() does not work properly.
If I use requestLayout, all the tree will measure and layout itself, and it's not a good way for a scrolling user experience.
Is there a way for only request layout on recycle child item ?
You need to notify your listView with changed of view so call notifyDataSetChanged(); from Uithread like this :
final ArrayAdapter adapter = ((ArrayAdapter) getListAdapter());
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
}
});

Categories

Resources