在适配器检测滚动方向(上/下)(Detecting the scrolling direction

2019-06-17 21:19发布

我试图模仿我的项目中谷歌Plus应用程序,因为它似乎是现在参考。

当滚动列表视图效果是非常好的,我希望做同样的事情。

我已经开始与LayoutAnimationController http://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。

所以我的问题,是有办法,如果我在我的适配器向上或向下滚动到检测?

Answer 1:

分配OnScrollListenerListView 。 创建指示用户是否向上或向下滚动的标志。 如果当前第一个可见项目位置等于比以前的第一个可见项目位置或多或少通过检查设置一个适当的值的标志。 把里面的那张支票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是真的还是假的getView()并相应地分配动画。



Answer 2:

最后我做这个:

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

}


Answer 3:

更复杂的解决方案(在列表视图中的长项高空作业)

  1. 创建自定义列表视图

     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(); } } 
  2. 覆盖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; } } }); 


Answer 4:

接受的答案并没有真正“检测”向上或向下滚动。 如果当前可见的项目真的是巨大的,它不会工作。 使用onTouchListener是要走的路。

这是代码片段我用:

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


Answer 5:

试试这个 。 我希望它可以帮助你。 逻辑与@Gal罗回答。

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;

        }
    });


Answer 6:

这里是我的方法:它可以让你多少你已经滚动更直接的反馈: OnScroll ,你可以得到你的列表中的第一项的顶部位置。 这是一个相当可靠的,立即得到实际的滚动位置的信息。

listView.getChildAt(0).getTop()


Answer 7:

我用这个更简单的解决方案:

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


    }

}


Answer 8:

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

基于最后一个可见项目的位置我决定列表视图是否会上涨或下跌。



Answer 9:

不依赖于视图/等职位一般的解决方案。 只是检查垂直滚动偏移,并将它与先前的滚动偏移量。 如果新值比老用户向下滚动,反之亦然更大。

// [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]


文章来源: Detecting the scrolling direction in the adapter (up/down)