About the conflict between SwipeRefreshLayout and listView sliding

SwipeRefreshLayout has been used in recent projects to handle pull-down refreshes such as listView and ExpandableListView, and pull-up to load more.

        My project uses SuperSwipeRefreshLayout in https://github.com/nuptboyzhb/SuperSwipeRefreshLayout. It feels good.

        Looking at the source code, I found that it listens to listView , ExpandableListView , ScrollView , and RecylerView sliding almost to judge whether these controls slide to the bottom to see if it is the last element. If it is the last element, it will start to load more events.

        I do not trigger loading more events for the above controls. So I played a little trick and wrapped a layer of LinearLayout around the listView. This way, more events will not be triggered to load. (The table asks why I don't want to trigger loading more, the reason is because the data is fully loaded, and don't ask me why I use full loading, because the design requires it. Don't ask me why the design does this, I don't know)

       But when the page is written, the tester sends a test report as shown in the figure:

This problem is actually a classic sliding event conflict problem, because the refresh was triggered when the first row of data was displayed by sliding, so the first row could not be displayed.

Of course, if SwipeRefreshLayout wraps ListView directly, there will be no such problem.

I specifically searched for the solution: Someone did this, wrote a subclass that inherits SwipeRefreshLayout, and then rewritten:

[java]  view plain  copy
  1. @Override  
  2.     publicvoid onScroll(AbsListView absListView, int firstVisibleItem,   
  3.                          int visibleItemCount, int totalItemCount) {  
  4.         View firstView = absListView.getChildAt(firstVisibleItem);  
  5.   
  6.         // When firstVisibleItem is the 0th bit. If firstView==null indicates that the list is empty and needs to be refreshed; or top==0 indicates that it has reached the top of the list and needs to be refreshed  
  7.         if (firstVisibleItem == 0 && (firstView == null || firstView.getTop() == 0)) {  
  8.             mSwipeView.setEnabled(true);  
  9.         } else {  
  10.             mSwipeView.setEnabled(false);  
  11.         }  
  12.         if (null != mOnScrollListener) {  
  13.             mOnScrollListener.onScroll(absListView, firstVisibleItem,  
  14.                     visibleItemCount, totalItemCount);  
  15.         }  
  16.     }  

代码是对的 但是 写个子类 有点花不来。

于是我思考与测试发现。如果 listView 先往上刷动 在往下滑动 时,listView 是可以相应这个滚动的事件的。

于是 有了个更直接的 办法,就是 监听 listView 的滑动代码如下:

[java]  view plain  copy
  1. huiYuanListView.setOnScrollListener(new AbsListView.OnScrollListener() {  
  2.                                 @Override  
  3.                                 public void onScrollStateChanged(AbsListView view, int scrollState) {  
  4.   
  5.                                 }  
  6.   
  7.                                 @Override  
  8.                                 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
  9.                                     View firstView = view.getChildAt(firstVisibleItem);  
  10.                                     if(firstVisibleItem ==0 && (firstView == null || firstView.getTop() == 0))  
  11.                                     {  
  12.                                         swipe_refresh.setEnabled(true);  
  13.                                         LogUtils.d("滑动","true");  
  14.                                     }  
  15.                                     else  
  16.                                     {  
  17.                                         swipe_refresh.setEnabled(false);  
  18.                                         LogUtils.d("滑动","false");  
  19.                                     }  
  20.                                 }  
  21.                             });  

It means that as long as the listView slides up and sees the data behind, I set SwipeRefreshLayout to be unavailable, so that when the listView slides up to see the previous data, the refresh event of SwipeRefreshLayout will not be triggered.

Set SwipeRefreshLayout to be available only when the listView is swiped to the top. so that it can trigger a refresh.


Finally, let's say that usually SwipeRefreshLayout should wrap a swipeable control, and it is a control, and should not wrap two swipeable controls, or a ViewGroup without sliding events.

If you wrap a ViewGroup without sliding, it will cause the problem of sliding conflict.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325581670&siteId=291194637