[ACCEPTED]-Detecting the scrolling direction in the adapter (up/down)-direction
Assign an OnScrollListener
to your ListView
. Create a flag which 8 indicates whether the user is scrolling 7 up or down. Set an appropriate value to 6 the flag by checking if the current first visible 5 item position equals to more or less than 4 the previous first visible item position. Put 3 that check inside onScrollStateChanged()
.
Sample code:
private int mLastFirstVisibleItem;
private boolean mIsScrollingUp;
public void onScrollStateChanged(AbsListView view, int scrollState) {
final ListView lw = getListView();
if (view.getId() == lw.getId()) {
final int currentFirstVisibleItem = lw.getFirstVisiblePosition();
if (currentFirstVisibleItem > mLastFirstVisibleItem) {
mIsScrollingUp = false;
} else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
mIsScrollingUp = true;
}
mLastFirstVisibleItem = currentFirstVisibleItem;
}
}
Check if 2 mIsScrollingUp
is true or false in getView()
, and assign the animations 1 accordingly.
I ended up by doing this:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.i("",position+" - "+lastposition);
if (position >= lastposition)
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
else
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
animation.setDuration(600);
set.addAnimation(animation);
row.startAnimation(set);
lastposition = position;
}
0
This is the easiest and simplest method 1 I came across. And it works like a charm.
view.addOnScrollListener(new View.OnScrollListener() {
@Override
public void onScrolled(@NonNull View view, int dx, int dy) {
if (dy > 0) {
//Scrolling down
} else if (dy < 0) {
//Scrolling up
}
}
});
More complex solution (working with long 2 items height in listview)
Create custom listview
public class ScrollDetectingListView extends ListView { public ScrollDetectingListView(Context context) { super(context); } public ScrollDetectingListView(Context context, AttributeSet attrs) { super(context,attrs); } public ScrollDetectingListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } //we need this protected method for scroll detection public int getVerticalScrollOffset() { return computeVerticalScrollOffset(); } }
Override 1 onScroll
listView.setOnScrollListener(new AbsListView.OnScrollListener() { private int mInitialScroll = 0; @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { int scrolledOffset = listView.getVerticalScrollOffset(); if (scrolledOffset!=mInitialScroll) { //if scroll position changed boolean scrollUp = (scrolledOffset - mInitialScroll) < 0; mInitialScroll = scrolledOffset; } } });
The accepted answer doesn't really "detect" scrolling 3 up or down. It won't work if the current 2 visible item is really huge. Using onTouchListener
is the 1 way to go.
This is the code snippet I used:
listView.setOnTouchListener(new View.OnTouchListener() {
float initialY, finalY;
boolean isScrollingUp;
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
switch(action) {
case (MotionEvent.ACTION_DOWN):
initialY = event.getY();
case (MotionEvent.ACTION_UP):
finalY = event.getY();
if (initialY < finalY) {
Log.d(TAG, "Scrolling up");
isScrollingUp = true;
} else if (initialY > finalY) {
Log.d(TAG, "Scrolling down");
isScrollingUp = false;
}
default:
}
if (isScrollingUp) {
// do animation for scrolling up
} else {
// do animation for scrolling down
}
return false; // has to be false, or it will freeze the listView
}
});
Try this . I hope it helps you . Logic From 1 @Gal Rom Answer .
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;
}
});
Here's my approach: It gets you more immediate 5 feedback on how much you've scrolled:
OnScroll
, you 4 can just get the Top position of the first 3 item in your list. It's a pretty reliable 2 to get actual scroll position information 1 immediately.
listView.getChildAt(0).getTop()
I've used this much simpler solution:
public class ScrollDetectingListView extends ListView
...
setOnScrollListener( new OnScrollListener()
{
private int mInitialScroll = 0;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
{
int scrolledOffset = computeVerticalScrollOffset();
boolean scrollUp = scrolledOffset > mInitialScroll;
mInitialScroll = scrolledOffset;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
}
0
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;
}
});
Based on the position of the last visible 2 item i decide whether Listview is going 1 up or down.
General solution that doesn't rely on positions 5 of views/etc. Just check the vertical scroll 4 offset and compare it to the previous scroll 3 offset. If the new value is greater than 2 the old the user is scrolling down, and 1 vice-versa.
// [START check vertical scroll direction]
int oldScrollOffset = 0;
listView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View view, int i, int i1, int i2, int i3) {
Boolean scrollDirectionDown;
int newScrollOffset = listView.computeVerticalScrollOffset();
if (newScrollOffset > oldScrollOffset) {
scrollDirectionDown = true;
} else {
scrollDirectionDown = false;
}
oldScrollOffset = newScrollOffset;
if (scrollDirectionDown) {
// Update accordingly for scrolling down
Log.d(TAG, "scrolling down");
} else {
// Update accordingly for scrolling up
Log.d(TAG, "scrolling up");
}
});
// [END check vertical scroll direction]
view.setOnTouchListener(new View.OnTouchListener() {
private long startClickTime;
float y0 = 0;
float y1 = 0;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
y0 = motionEvent.getY();
startClickTime = System.currentTimeMillis();
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
if (System.currentTimeMillis() - startClickTime < ViewConfiguration.getTapTimeout()) {
// Touch was a simple tap. Do whatever.
} else {
y1 = motionEvent.getY();
// Touch was a not a simple tap.
if (y1 - y0 > 50) {
// this is down
} else if (y1 - y0 < 50) {
Log.d("daniY", "-");
// this is up
}
}
}
return true;
}
});
this worked for me, and this will work on 2 detecting the direction of scrolling on 1 all views i think.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.