I\'m running into a bit of a problem. What I\'m doing: I\'ve got a ListView which has got some images in it. To make the scrolling smoother I\'ve disabled the images to show up
I have had this same problem and posted a workaround on the bug list:
For anybody still running into this problem (as I was last week) a workaround that works for me is the following: If android SDKInt == 7 set a
onTouchListener
on the(Abs)ListView
In that
onTouchListener
when theOnTouch
event action isMotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL
you force aonScrollStateChanged
with first aSCROLL_STATE_FLING
and then aSCROLL_STATE_IDLE
Code example: In the
onCreate
:if(androidSDKInt <= 7){ listViewDateSelector.setOnTouchListener(new FingerTracker(onScrollListener)); }
Then add a private class with:
private class FingerTracker implements View.OnTouchListener { private OnScrollListener myOnScrollListener; public FingerTracker(OnScrollListener onScrollListener){ myOnScrollListener = onScrollListener; } public boolean onTouch(View view, MotionEvent event) { final int action = event.getAction(); boolean mFingerUp = action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL; if (mFingerUp) { myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_FLING); myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_IDLE); } return false; } }
I had the same problem, so my solution was to just detect if the scrollview position has reached the last page and in that case always load the images regardless of the scroll state (since the problem seems to always occur when the user flings to the end of the listview). So modifying your code you would have:
mList.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
mListAdapter.setIsScrolling(scrollState != SCROLL_STATE_IDLE);
Log.i(this, "scrollStateChanged" + scrollState);
int first = view.getFirstVisiblePosition();
int count = view.getChildCount();
if (scrollState == SCROLL_STATE_IDLE || (first + count > mListAdapter.getCount()) ) {
mList.invalidateViews();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
I ran into the same issue with a RecyclerView
.
Jason Burke's answer is correct, but I'll provide an alternate way of checking if you are at the beginning/end of the RecyclerView
/ListView
.
I do it in onScrolled
instead of onScrollStateChanged
since I don't trust that I get a state changed event in the case when you scroll/fling to the edge of the RecyclerView
.
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
updateUi()
}
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
/* If the user scrolls to the edges of the recyclerview, we can't trust that we get the SCROLL_STATE_IDLE state.
* Therefore we have to update the view here in onScrolled for these cases
*/
if (!recyclerView.canScrollVertically(1) || !recyclerView.canScrollVertically(-1)) {
updateUi()
}
}
}
In my case it was actually a horizontal RecyclerView, so I had to do this instead:
if (!recyclerView.canScrollHorizontally(1) || !recyclerView.canScrollHorizontally(-1)) {
updateUi()
}