Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwipeRefreshLayout interfering with setOnScrollListener

Everytime I scroll the list up or down I hide (or unhide) some views with OnScrollListener. Here is the code attached to my 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;

                }
            }
        });

Layout:

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

Ever since I added the SwipeRefreshLayout, I do not get anything when I Log inside the listener above. How can I use both of these items together?

EDIT: It seems like this is what I need but I can't make it work still

As part of that article I added this in onScroll, tho it doesn't seem to work.

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

EDIT2: THIS IS THE HEART OF THE ISSUE: It seems the onScroll method fires when the Activity first starts and the list loads and then never more again.

like image 724
TheLettuceMaster Avatar asked Dec 13 '14 22:12

TheLettuceMaster


People also ask

Can child scroll up SwipeRefreshLayout?

Can Child scroll up SwipeRefreshLayout? SwipeRefreshLayout is a ViewGroup that can hold only one scrollable view as a child.

What is SwipeRefreshLayout?

The swipe-to-refresh user interface pattern is implemented entirely within the SwipeRefreshLayout widget, which detects the vertical swipe, displays a distinctive progress bar, and triggers callback methods in your app.

How to disable pull to refresh in android studio?

To disable the gesture and progress animation, call setEnabled(false) on the view. This layout should be made the parent of the view that will be refreshed as a result of the gesture and can only support one direct child.


1 Answers

I had the same issue with RecyclerView and ListView. Scrolling downwards for whatever amount of items, it was impossible to return to the top of the list.

This will disable the SwipeRefreshLayout until the first visible item or any item position is visible. You can also bind different scroll listeners along this one. Make sure you enable (if previously disabled) SwipeRefreshLayout whenever you repopulate the listivew.

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

Edit:

lv.setOnScrollListener(new SwipeRefreshLayoutToggleScrollListenerListView(mSwiperLayout){
   //override methods here, don't forget the super calls. 
});
like image 76
Nikola Despotoski Avatar answered Oct 18 '22 20:10

Nikola Despotoski