SwipeRefreshLayout干扰setOnScrollListener

时间:2014-12-13 22:32:57

标签: android listview swiperefreshlayout onscrolllistener

每次我向上或向下滚动列表时,我都会使用OnScrollListener隐藏(或取消隐藏)某些视图。以下是我ListView附带的代码。

lv.setOnScrollListener(new OnScrollListener() {

            private int mLastFirstVisibleItem;
            private boolean mIsScrollingUp = true;
            private LinearLayout ll = (LinearLayout) getActivity()
                    .findViewById(R.id.llSearchPlaces);

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                                 int visibleItemCount, int totalItemCount) {



                if (view.getId() == lv.getId()) {
                    final int currentFirstVisibleItem = lv
                            .getFirstVisiblePosition();
                    if (currentFirstVisibleItem > mLastFirstVisibleItem) {

                        if (mIsScrollingUp == true) {
                            mIsScrollingUp = false;
                             Log.i("a", "scrolling down...");

                            floatingActionButton.hide();

                            Animation animation = new TranslateAnimation(0, 0,
                                    0, 200);
                            animation.setDuration(300);
                            animation
                                    .setAnimationListener(new AnimationListener() {

                                        @Override
                                        public void onAnimationEnd(
                                                Animation animation) {
                                            ll.setVisibility(View.INVISIBLE);
                                        }

                                        @Override
                                        public void onAnimationRepeat(
                                                Animation animation) {
                                        }

                                        @Override
                                        public void onAnimationStart(
                                                Animation animation) {
                                        }
                                    });

                            ll.startAnimation(animation);
                        }

                    } else if (currentFirstVisibleItem < mLastFirstVisibleItem) {

                        if (mIsScrollingUp == false) {
                            mIsScrollingUp = true;
                            floatingActionButton.show();
                             Log.i("a", "scrolling up...");

                            Animation animation = new TranslateAnimation(0, 0,
                                    200, 0);
                            animation.setDuration(400);
                            animation
                                    .setAnimationListener(new AnimationListener() {

                                        @Override
                                        public void onAnimationEnd(
                                                Animation animation) {

                                        }

                                        @Override
                                        public void onAnimationRepeat(
                                                Animation animation) {

                                        }

                                        @Override
                                        public void onAnimationStart(
                                                Animation animation) {
                                            ll.setVisibility(View.VISIBLE);

                                        }
                                    });

                            ll.startAnimation(animation);

                        }
                    }

                    mLastFirstVisibleItem = currentFirstVisibleItem;

                }
            }
        });

布局:

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ListView
        android:id="@id/android:list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fadeScrollbars="true"
        android:listSelector="#00000000"
        android:scrollbars="none" />

</android.support.v4.widget.SwipeRefreshLayout>

自从我添加了SwipeRefreshLayout之后,当我在上面的监听器中Log时,我什么都得不到。我怎样才能同时使用这两个项目?

编辑:似乎this是我需要的,但我无法让它继续工作

作为该文章的一部分,我在onScroll中添加了此内容,但它似乎无效。

        if (firstVisibleItem == 0) {
            swipeLayout.setEnabled(true);
        } else {
            swipeLayout.setEnabled(false);
        }

EDIT2 :这是问题的核心:似乎onScroll方法会在“活动”首次启动并且列表加载后再次启动时再触发。

3 个答案:

答案 0 :(得分:4)

我在RecyclerViewListView时遇到了同样的问题。无论向下滚动任何数量的项目,都无法返回到列表的顶部。

这将禁用SwipeRefreshLayout,直到第一个可见项目或任何项目位置可见。您还可以沿此绑定不同的滚动侦听器。确保在重新填充listivew时启用(如果先前已禁用)SwipeRefreshLayout

public class SwipeRefreshLayoutToggleScrollListenerListView implements AbsListView.OnScrollListener {
    private List<AbsListView.OnScrollListener> mScrollListeners = new ArrayList<AbsListView.OnScrollListener>();
    private int mExpectedVisiblePosition = 0;

    public SwipeRefreshLayoutToggleScrollListenerListView(SwipeRefreshLayout mSwipeLayout) {
        this.mSwipeLayout = mSwipeLayout;
    }

    private SwipeRefreshLayout mSwipeLayout;
    public void addScrollListener(AbsListView.OnScrollListener listener){
        mScrollListeners.add(listener);
    }
    public boolean removeScrollListener(AbsListView.OnScrollListener listener){
        return mScrollListeners.remove(listener);
    }
    public void setExpectedFirstVisiblePosition(int position){
        mExpectedVisiblePosition = position;
    }

    private void notifyOnScrolled(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){
        for(AbsListView.OnScrollListener listener : mScrollListeners){
            listener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
        }
    }
    private void notifyScrollStateChanged(AbsListView view, int scrollState){
        for(AbsListView.OnScrollListener listener : mScrollListeners){
            listener.onScrollStateChanged(view, scrollState);
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
      notifyScrollStateChanged(view, scrollState);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        notifyOnScrolled(view, firstVisibleItem, visibleItemCount, totalItemCount);
        if(firstVisibleItem != RecyclerView.NO_POSITION)
            mSwipeLayout.setEnabled(firstVisibleItem == mExpectedVisiblePosition);
    }
}

编辑:

lv.setOnScrollListener(new SwipeRefreshLayoutToggleScrollListenerListView(mSwiperLayout){
   //override methods here, don't forget the super calls. 
});

答案 1 :(得分:3)

您应该覆盖SwipeRefreshView的{​​{3}}。轮询此方法是为了了解包含的View是否要向上滚动:

包含任意arbritrary视图的可设置界面的扩展名:

public class SwipeRefreshWrapper extends SwipeRefreshLayout {
    private ScrollResolver mScrollResolver;

    public SwipeRefreshWrapper(Context context) {
        super(context);
    }

    public SwipeRefreshWrapper(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollResolver(ScrollResolver scrollResolver) {
        mScrollResolver = scrollResolver;
    }

    @Override
    public boolean canChildScrollUp() {
        if(mScrollResolver != null){
            return mScrollResolver.canScrollUp();
        }else {
            return super.canChildScrollUp();
        }
    }

    public static interface ScrollResolver{
        public boolean canScrollUp();
    }
}

用法(ListView也有一个不错的方法:canScrollVertically()):

final SwipeRefreshWrapper wrapper = (SwipeRefreshWrapper) rootView.findViewById(R.id.wrapper);
final ListView list = (ListView) rootView.findViewById(R.id.list);

wrapper.setScrollResolver(new SwipeRefreshWrapper.ScrollResolver() {
                              @Override
                              public boolean canScrollUp() {
                                 return list.canScrollVertically(-1);
                              }
                          });

答案 2 :(得分:2)

yourListview.setOnScrollListener(new OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            boolean enable = false;
            if(timelogListView != null && timelogListView.getChildCount() > 0){
                boolean firstItemVisible = timelogListView.getFirstVisiblePosition() == 0;
                boolean topOfFirstItemVisible = timelogListView.getChildAt(0).getTop() == 0;
                enable = firstItemVisible && topOfFirstItemVisible;
            }
            swipeLayout.setEnabled(enable); 
            if(firstVisibleItem+visibleItemCount == totalItemCount && totalItemCount!=0)
            {
                if(flag_loading == false)
                {
                    flag_loading = true;
                    ConnectionDetector conn = new ConnectionDetector(getActivity());
                    if(conn.isConnectingToInternet()){
                        // call for your pagination async
                    }else{

                    }
                }
            }
        }
    });

默认情况下:private boolean flag_loading = false;并且在您的分页异步if(YourListview.size()&lt; 20){flag_loading = true; } else {flag_loading = false; }