1

當您刷新Facebook頁面活動中,SwipeRefreshLayout似乎被放置在活動課中,並從屏幕頂部歸結:實施SwipeRefreshLayout在片段

swipetorefresh

什麼似乎是一個它下面的RecyclerView被刷新。在SwipeRefreshLayout將自動激活之前,您還需要一直滾動到屏幕的頂部 - 所以如果工具欄中的ImageView未出現在屏幕的頂部,那麼當您向下滑動時,實際上只是滾動RecyclerView。在下面的屏幕截圖中,我們可以看到頂部的ImageView不可見,所以我們只是滾動我們的recyclerview。

below is a scroll

我想實現我的應用程序做的XML看起來類似於首款Facebook截圖我上面貼以下類似的東西 - 我的活動有「swipeRefresh圓圈圖標」從出來頂部,並遵循用於與ImageView建立toolbar的標準佈局的xml:

主要活動XML:

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

    <android.support.design.widget.CoordinatorLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/coordinatorlayout" 
     > 

     <android.support.design.widget.AppBarLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:id="@+id/appbar" 
      > 

      <android.support.design.widget.CollapsingToolbarLayout 
       android:id="@+id/collapsing_toolbar" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       app:contentScrim="?attr/colorPrimary" 
       android:background="@color/white" 
       app:expandedTitleTextAppearance="@color/transparent" 
       app:layout_scrollFlags="scroll|exitUntilCollapsed" 
       > 

        <ImageView 
         android:id="@+id/backdrop" 
         android:contentDescription="@string/photo" 
         android:layout_width="match_parent" 
         android:background="@color/white" 
         android:layout_height="192dp" 
         android:scaleType="centerCrop" 
         android:fitsSystemWindows="true" 
         /> 

       <android.support.v7.widget.Toolbar 
        android:id="@+id/toolbar" 
        android:layout_width="match_parent" 
        android:layout_height="?attr/actionBarSize" 
        app:layout_collapseMode="pin"/> 

      </android.support.design.widget.CollapsingToolbarLayout> 

     </android.support.design.widget.AppBarLayout> 

      <FrameLayout 
       android:id="@+id/container" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:fitsSystemWindows="true" 
       app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

       <android.support.v4.widget.NestedScrollView 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:fillViewport="true" 
        > 
       </android.support.v4.widget.NestedScrollView> 

      </FrameLayout> 

    </android.support.design.widget.CoordinatorLayout> 

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

但是,SwipeRefreshLayout需要完全關注該活動,包括我的Fragment中的任何滾動操作,這些滾動操作在我的FrameLayout內膨脹,嵌入到我的主要活動xml中。我膨脹的Fragment是一個RecyclerView,它滾動上下類似於Facebook的RecyclerView

要想從這個問題的時候,我知道,我只能從我的Activity XML刪除SwipeRefreshLayout,並把它與我的Fragment XML,但後來我SwipeRefresh圓圈圖標只會向屏幕月底開始的,而不是最佳。

不知道Facebook如何設法阻止SwipeRefreshLayout獲得所有滾動操作的全部焦點 - 有誰知道他們是如何實現他們的SwipeRefreshLayout

這是我的片段XML代碼:

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/snackbarPosition"> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/post_container" 
     android:background="#E0E0E0"> 

     <ProgressBar 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/progresswheel" 
      android:layout_margin="32dp" 
      android:layout_centerHorizontal="true" 
      android:visibility="gone" 
      tools:visibility="visible"/> 

      <android.support.v7.widget.RecyclerView 
       android:id="@+id/my_recycler_view" 
       android:scrollbars="vertical" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 
      </android.support.v7.widget.RecyclerView> 

    </RelativeLayout> 

</android.support.design.widget.CoordinatorLayout> 
+0

把'SwipeRefreshLayout'放在你的'Fragment'中,而不是'Activity'作爲父項。 –

+0

是的 - 正如我在我的問題中提到的,但這不是首選選項,因爲刷新刷新圈將從頁面中間開始,而不是在頂部。 – Simon

+0

可能是你做錯了。請發佈您的完整代碼,包括片段部分。 –

回答

2

行 - 我終於想通了這一點。

這並不容易,但解決方案實際上是取出片段類並將其替換爲正常的recyclerview。

在XML:

<?xml version="1.0" encoding="utf-8"?> 


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

    <android.support.design.widget.CoordinatorLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/coordinatorlayout" 
     android:fitsSystemWindows="true" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     xmlns:android="http://schemas.android.com/apk/res/android"> 

     <android.support.design.widget.AppBarLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:id="@+id/appbar" 
      android:fitsSystemWindows="true" 
      > 
      <android.support.design.widget.CollapsingToolbarLayout 
       android:id="@+id/collapsing_toolbar" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       app:contentScrim="?attr/colorPrimary" 
       android:background="@color/white" 
       app:expandedTitleMarginStart="48dp" 
       app:expandedTitleMarginEnd="64dp" 
       android:fitsSystemWindows="true" 
       app:expandedTitleTextAppearance="@color/transparent" 
       app:layout_scrollFlags="scroll|exitUntilCollapsed" 
       > 

        <ImageView 
         android:layout_width="match_parent" 
         android:layout_height="300dp" 
         android:scaleType="centerCrop" 
         android:fitsSystemWindows="true" 
         android:id="@+id/photo" 
         app:layout_collapseMode="parallax" 
         android:src="@drawable/hand_gestures"/> 

       <android.support.v7.widget.Toolbar 
        android:id="@+id/toolbar" 
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
        android:layout_width="match_parent" 
        android:layout_height="?attr/actionBarSize" 
        app:layout_collapseMode="pin"/> 


      </android.support.design.widget.CollapsingToolbarLayout> 

     </android.support.design.widget.AppBarLayout> 

     <android.support.v7.widget.RecyclerView 
      android:layout_width="match_parent" 
      android:fitsSystemWindows="true" 
      android:fillViewport="true" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior" 
      android:layout_height="match_parent" 
      android:id="@+id/recyclerview"> 

     </android.support.v7.widget.RecyclerView> 

    </android.support.design.widget.CoordinatorLayout> 

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

然後,你將需要遵循這個線程解決方案:Android: CollapsingToolbarLayout and SwipeRefreshLayout get stuck得到swipeToRefreshLayout正常工作。

在你的片段/活性,使其實現AppBarLayout:從線程複製 -

您可以通過執行以下做到這一點。OnOffsetChangedListener(現在,當工具欄完全展開的清爽啓用):

@Override 
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { 
    if (collapsingToolbarLayout.getHeight() + verticalOffset < 2 * ViewCompat.getMinimumHeight(collapsingToolbarLayout)) { 
     swipeRefreshLayout.setEnabled(false); 
    } else { 
     swipeRefreshLayout.setEnabled(true); 
    } 
} 

覆蓋的onPause()&的onResume()在@blackcj答案:

@覆蓋 公共無效的onResume(){ 超.onResume(); appBarLayout.addOnOffsetChangedListener(this); }

@Override 
public void onPause() { 
    super.onPause(); 
    appBarLayout.removeOnOffsetChangedListener(this); 
} 

然後設置LinearLayoutManager您recyclerView:

LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); 
layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
recyclerView.setLayoutManager(layoutManager); 

對我來說這是一名魅力,第一appBarlayout被擴大,然後才swipeRefreshLayout觸發耳目一新。