Is there a way to identify if listview is being scroll up or down?
OnScrollListener doens't help me in this case.
Thanks in advance!
Is there a way to identify if listview is being scroll up or down?
OnScrollListener doens't help me in this case.
Thanks in advance!
this is a simple implementation:
lv.setOnScrollListener(new OnScrollListener() {
private int mLastFirstVisibleItem;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(mLastFirstVisibleItem<firstVisibleItem)
{
Log.i("SCROLLING DOWN","TRUE");
}
if(mLastFirstVisibleItem>firstVisibleItem)
{
Log.i("SCROLLING UP","TRUE");
}
mLastFirstVisibleItem=firstVisibleItem;
}
});
There is a method in ScrollViews
that reports the shifting of scrolls. It is called onScrollChanged()
. However, it is declared protected, so you must create a wrapper class to gain access. For the usage of the method, please check android docs.
First, create an interface to expose the protected method
public interface OnScrollListener {
void onScrollChanged(int x, int y, int oldx, int oldy);
}
Then, create your wrapper and extend ScrollView
public class ReportingScrollView extends ScrollView {
private OnScrollListener onScrollListener = null;
public ReportingScrollView(Context context) {
super(context);
}
public ReportingScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ReportingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnScrollListener(OnScrollListener onScrollListener) {
this.onScrollListener = onScrollListener;
}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if (onScrollListener != null) {
onScrollListener.onScrollChanged(x, y, oldx, oldy);
}
}
}
Finally, include it in your XML layout like a custom view, and attach listeners like usual.
<your.package.ReportingScrollView />
scrollingandtrolling.setOnScrollListener(new OnScrollListener() {...});
An easy and working solution.
private int lastPosition = -1;
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if(lastPosition == firstVisibleItem)
{
return;
}
if(firstVisibleItem > lastPosition)
{
Logger.print("Going Down");
}
else
{
Logger.print("Going Up");
}
lastPosition = firstVisibleItem;
}
for whom ever still looking for an answer for kotlin, this works for it
MainListView.setOnScrollListener(object :AbsListView.OnScrollListener {
// var VisibleItem: Int = 0
override fun onScroll(p0: AbsListView?, FirstVisibleItem: Int, i2: Int, i3: Int) {
/*
if(VisibleItem < FirstVisibleItem)
{
Toast.makeText(applicationContext,"Scrolling Down",Toast.LENGTH_SHORT).show()
fab.hide()
}
if(VisibleItem >FirstVisibleItem)
{
fab.show()
Toast.makeText(applicationContext,"Scrolling Up",Toast.LENGTH_SHORT).show()
}
VisibleItem=FirstVisibleItem;
*/
}
override fun onScrollStateChanged(p0: AbsListView?, p1: Int) {
if (p1 == 1) {
fab.hide()
} else {
fab.show()
}
}
})
}
Uncomment to use an alternative method.
The solution given by Some Noob Student is good: you have to create a wrapper to use the protected onScrollChanged(int x, int y, int oldx, int oldy) method, which is triggered more often then the standard AbsListView.OnScrollListener.onScrollStateChanged(AbsListView view, int scrollState).
Unfortunately the onScrollChanged() always returns 0 as parameters, no matter how I scroll, and seems to detect only when the scroll ends, reaching the top or the bottom of the list.
So I used the following code to detect the right direction of the scrolling: it uses the getTop() of the first visible item but uses also its position to understand when the first item is no more visible; during this item transition, the scroll direction is given by the item position itself.
@Override
public void onScrollChanged(int x, int y, int oldx, int oldy) {
if(listView.getChildAt(0) != null) {
int scrollingDir = NO_SCROLLING;
int firstChildTop = listView.getChildAt(0).getTop();
if (listView.getFirstVisiblePosition() == mLastFirstVisiblePosition) {
if (mLastFirstChildTop < firstChildTop) {
//Scrolling DOWN
scrollingDir = SCROLLING_DOWN;
} else if (mLastFirstChildTop > firstChildTop) {
//Scrolling UP
scrollingDir = SCROLLING_UP;
}
} else if(listView.getFirstVisiblePosition() > mLastFirstVisiblePosition) {
//Scrolling UP
scrollingDir = SCROLLING_UP;
} else {
//Scrolling DOWN
scrollingDir = SCROLLING_DOWN;
}
mLastFirstVisiblePosition = listView.getFirstVisiblePosition();
mLastFirstChildTop = firstChildTop;
switch(scrollingDir) {
case SCROLLING_DOWN:
//Your DOWN scrolling code here
break;
case SCROLLING_UP:
//Your UP scrolling code here
break;
default:
case NO_SCROLLING:
break;
}
}
}
list.setOnScrollListener(new OnScrollListener() {
int last_item;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(last_item<firstVisibleItem+visibleItemCount-1){
System.out.println("List is scrolling upwards");
}
else if(last_item>firstVisibleItem+visibleItemCount-1){
System.out.println("List is scrolling downwards");
}
last_item = firstVisibleItem+visibleItemCount-1;
}
});
Here based on the last visible item i decide whether the list is going up or down