简体   繁体   中英

Android Swipe Refresh Layout scroll up to refresh

I've implemented a swipe refresh layout for my grid view and it works perfectly if I pull (scroll) downwards for the refresh to be called.

However, I'm trying to figure out how to refresh when the user scrolls up. So when the user reaches the last of the items in the grid (my limit is 10) so when the user sees all ten and then pulls upwards or tries to continue to scroll how can I then refresh?

Any help is appreciated.

See my answer in stackoverflow

SwipeRefreshLayout from Android Support Library version 21 does not support pull from bottom. I have made modification SwipeRefreshLayoutBottom with is based on original SwipeRefreshLayout code. It is fully based on original Google code with just inversion of coordinates and newly writed canChildScrollDown method. All modification are marked as TODO.

Bitbucker repository

so people either a: don't know the answer to this question or b: they're not willing to share the knowledge.

Anyway after a long time I came up with my own solution. I added a scroll listener to my grid, and calculated when I scrolled to the bottom of the screen, at this point I recall the onRefresh() method from the swipe to refresh...

EDIT to add further info

So, after I did some research to calculate when the user reached the bottom of a grid view I followed questions like this and others to get that. Below is my code that I had to alter in order have it work with the native refreshing functionality. My alterations were to prevent constant refreshing. So included in my if statement is a check that it's not currently refreshing, so when I reached the bottom it refreshed, but I didn't have that check so it constantly refreshed. I then had to do a check against the total amount of items in my grid, as when the user reached the last item (very last item) the app also kept refreshing and there was nothing to break the cycle. Hopefully this is of some help...

        worldBeersGrid.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {

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

            int position = firstVisibleItem+visibleItemCount;
            int limit = totalItemCount;
            int totalItems = sharedpreferences.getInt("WORLD ITEM COUNT", 0);

            Log.i("TOTAL WORLD ITEMS", String.valueOf(totalItems));
            Log.i("LIMIT :::::::::::: ", String.valueOf(limit));
            Log.i("POSITION ::::::::::::", String.valueOf(position));
            Log.i("REFRESHING :::::::::::::::", String.valueOf(swipeRefreshLayout.isRefreshing()));

            if(position>=limit && totalItemCount>0 && !swipeRefreshLayout.isRefreshing() && position <totalItems){
                swipeRefreshLayout.setRefreshing(true);
                //In the below method I made my call to my ws...
                onRefresh();
            }
        }
    });

You try this way

listView.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(listView != null && listView.getChildCount() > 0){
        // check if the first item of the list is visible
        boolean firstItemVisible = listView.getFirstVisiblePosition() == 0;
        // check if the top of the first item is visible
        boolean topOfFirstItemVisible = listView.getChildAt(0).getTop() == 0;
        // enabling or disabling the refresh layout
        enable = firstItemVisible && topOfFirstItemVisible;
    }
    swipeRefreshLayout.setEnabled(enable);
}});

Another answer if anybody is still interested. In order to refresh when scrolling down, I've implemented the onRefreshListerner() on the swipeRefreshLayout.

    swipeRefreshLayout = (SwipeRefreshLayout) getView().findViewById(R.id.swipe_messages);
    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            swipeRefreshLayout.setRefreshing(true);

            ( new Handler()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    refresh();
                }
            }, 1000);
        }
    });

But in order to refresh when scrolling up and only when I've got to the end of the list, I've implemented OnTouchListener() on the list which includes the swipeRefreshLayout.setRefreshing(true) to start the effect:

    listView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == android.view.MotionEvent.ACTION_UP) {

                if (listView.getLastVisiblePosition() == listView.getAdapter().getCount() -1 &&
                        listView.getChildAt(listView.getChildCount() - 1).getBottom() <= listView.getHeight())
                {

                    swipeRefreshLayout.setRefreshing(true);

                    ( new Handler()).postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            refresh();
                        }
                    }, 1000);

                }
            }
            return false;
        }
    });

Of course you have to disable the swipeRefreshLayout after updating your list:

public void refresh (){
    //Do something neat here to refresh your list
    swipeRefreshLayout.setRefreshing(false);
}

I've used this answer to know when I've got to the end of the list:

https://stackoverflow.com/a/10235887/6144027

I have another way:

binding.contentListScroll.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
                if (!binding.contentListScroll.canScrollVertically(1))
                {
                    binding.swiperefresh.setRefreshing(true);
                    YourRefreshMethod();
                }
            }
            return false;
        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM