2014-12-24 22 views
4

我的佈局有問題,我在裏面創建了帶有RecyclerView的SwipeRefreshLayout。 在Android 4.2.2+所有工作都很好,但是在2.3.4我無法向上滾動,因爲在RecyclerView中的任何地方它都會刷新,我必須向下滾動然後向上滾動。使用RecyclerView滾動Swip​​eRefreshLayout在Android 2.2中的任意位置刷新

這是我的代碼:

<android.support.v4.widget.SwipeRefreshLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/forum_swipe_container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

    <android.support.v7.widget.RecyclerView 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/LVP" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:gravity="center" /> 
</android.support.v4.widget.SwipeRefreshLayout> 

我發現這個問題:https://code.google.com/p/android/issues/detail?id=78191,但沒有一個解決方案。 任何想法如何解決它?

回答

1

您可以覆蓋的方法canChildScrollUp()在SwipeRefreshLayout這樣的:

public boolean canChildScrollUp() { 
    if (mTarget instanceof RecyclerView) { 
     final RecyclerView recyclerView = (RecyclerView) mTarget; 
     RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); 
     if (layoutManager instanceof LinearLayoutManager) { 
      int position = ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition(); 
      return position != 0; 
     } else if (layoutManager instanceof StaggeredGridLayoutManager) { 
      int[] positions = ((StaggeredGridLayoutManager) layoutManager).findFirstCompletelyVisibleItemPositions(null); 
      for (int i = 0; i < positions.length; i++) { 
       if (positions[i] == 0) { 
        return false; 
       } 
      } 
     } 
     return true; 
    } else if (android.os.Build.VERSION.SDK_INT < 14) { 
     if (mTarget instanceof AbsListView) { 
      final AbsListView absListView = (AbsListView) mTarget; 
      return absListView.getChildCount() > 0 
        && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) 
          .getTop() < absListView.getPaddingTop()); 
     } else { 
      return mTarget.getScrollY() > 0; 
     } 
    } else { 
     return ViewCompat.canScrollVertically(mTarget, -1); 
    } 
} 
+0

如果它是一個LinearLayoutManager,如果setReverseLayout設置爲true,那麼您的解決方案可能不起作用。相反,它應該使用canScrollVertically – yigit

5

不幸的是,這是一個已知的問題,將其固定在將來的版本。

https://code.google.com/p/android/issues/detail?id=78191

同時,如果您需要緊急修復,在SwipeRefreshLayout.java覆蓋canChildScrollUp並調用recyclerView.canScrollVertically(mTarget, -1)。因爲在薑餅後添加了canScrollVertically,您還需要複製該方法並在recyclerview中實施。

或者,如果您使用的是LinearLayoutManager,則可以致電findFirstCompletelyVisibleItemPosition

抱歉給您帶來不便。

+0

尚未修復尚未支持的庫('com.android.support:appcompat-v7:21.0.3') –

+0

@yigit我仍然遇到這個問題,在一個SwipeRefreshLayout內的一個RecyclerView在一個FrameLayout在ViewPager中。使用com.android.support:appcompat-v7:23.2.1是否應該解決? – gbhall

6

覆蓋RecyclerView的方法OnScrollStateChanged

mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { 

      @Override 
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
       // TODO Auto-generated method stub 
       //super.onScrollStateChanged(recyclerView, newState); 
       try { 
        int firstPos = mLayoutManager.findFirstCompletelyVisibleItemPosition(); 
        if (firstPos > 0) { 
         mSwipeRefreshLayout.setEnabled(false); 
        } else { 
         mSwipeRefreshLayout.setEnabled(true); 
         if(mRecyclerView.getScrollState() == 1) 
          if(mSwipeRefreshLayout.isRefreshing()) 
          mRecyclerView.stopScroll(); 
        } 

       }catch(Exception e) { 
        Log.e(TAG, "Scroll Error : "+e.getLocalizedMessage()); 
       } 
      } 

檢查刷卡刷新令人耳目一新,並嘗試向上滾動,然後你有錯誤,所以當刷卡刷新是怎麼回事,我試圖做到這一點mRecyclerView.stopScroll();

+0

由於我在SwipeRefreshLayout中有emptyView和RecyclerView,所以只有這個方法對我有效。 (子類化SwipeRefreshLayout並重寫'canChildScrollUp()'雖然在沒有任何項目時會顯示我的emptyView,但我不明白爲什麼try/catch是必需的? – janakagamini

3

你可以基於回收站的滾動功能禁用/啓用刷新佈局

public class RecyclerSwipeRefreshHelper extends RecyclerView.OnScrollListener{ 

    private static final int DIRECTION_UP = -1; 


    private final SwipeRefreshLayout refreshLayout; 

    public RecyclerSwipeRefreshHelper(
      SwipeRefreshLayout refreshLayout) { 
     this.refreshLayout = refreshLayout; 
    } 


    @Override 
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
     super.onScrolled(recyclerView, dx, dy); 
     refreshLayout.setEnabled((recyclerView.canScrollVertically(DIRECTION_UP))); 
    } 
} 
4

我修復了使用下面的代碼:

private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() { 
    @Override 
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
     LinearLayoutManager manager = ((LinearLayoutManager)recyclerView.getLayoutManager()); 
     boolean enabled =manager.findFirstCompletelyVisibleItemPosition() == 0; 
     pullToRefreshLayout.setEnabled(enabled); 
    } 
}; 

然後,你需要使用setOnScrollListeneraddOnScrollListener取決於如果您有一個或更多的聽衆。

相關問題