检测适配器中的滚动方向(上/下)

问题描述 投票:16回答:10

我正在尝试在我的项目中模仿Google Plus应用程序,因为现在看来它是参考。

滚动时的列表视图效果非常好,我想做类似的事情。

我已经开始使用LayoutAnimationControllerhttp://android-er.blogspot.be/2009/10/listview-and-listactivity-layout.html

LayoutAnimationController controller 
   = AnimationUtils.loadLayoutAnimation(
     this, R.anim.list_layout_controller);
  getListView().setLayoutAnimation(controller);

而且这似乎很糟糕,因为并非所有元素都具有动画效果:

所以我最终通过使用适配器的getView并使用了它:

        AnimationSet set = new AnimationSet(true);

        Animation animation = new AlphaAnimation(0.0f, 1.0f);
        animation.setDuration(800);
        set.addAnimation(animation);

        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);

结果很棒,我对此非常满意!

不幸的是,它仅在我从列表的顶部滚动到底部时才有效!

我想使其在另一侧滚动时起作用,我需要稍微改变一下TranslateAnimation。

所以,我的问题是,有什么方法可以检测我是在适配器中向上还是向下滚动?

android listview animation scroll direction
10个回答
0
投票

这是我遇到的最简单的方法。它就像一种魅力。

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
                    }
                }
            });

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;
        }
    });

22
投票

OnScrollListener分配给OnScrollListener。创建一个标志,指示用户是向上滚动还是向下滚动。通过检查当前first可见项位置是否等于或大于先前的first可见项位置,为标志设置适当的值。将该支票放入ListView

示例代码:

onScrollStateChanged()

检查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; } } 中的mIsScrollingUp是真还是假,并相应地分配动画。


19
投票

我最终通过这样做:

getView()

5
投票

更复杂的解决方案(在列表视图中使用较长的项目高度)

  1. 创建自定义列表视图

    @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;
    
    }
    
  2. Override onScroll

    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();
        }
    }
    

5
投票

接受的答案并没有真正“检测到”向上或向下滚动。如果当前可见项目确实很大,它将无法正常工作。使用 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; } } }); 是可行的方法。

这是我使用的代码段:

onTouchListener

4
投票

尝试一下。希望对您有帮助。 @Gal Rom答案提供的逻辑。

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
    }
});

2
投票

[这是我的方法:它为您滚动了多少内容提供了更直接的反馈: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; } }); ,您只需获取列表中第一项的顶部位置。立即获得实际的滚动位置信息非常可靠。

OnScroll

0
投票

我使用了这个简单得多的解决方案:

listView.getChildAt(0).getTop()

...

public class ScrollDetectingListView extends ListView

0
投票
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) {


    }

}

根据最后一个可见项目的位置,我决定Listview是向上还是向下。

© www.soinside.com 2019 - 2024. All rights reserved.