25


我已經使用Android應用程序庫使用工具欄和TabLayout製作應用程序。
實際上有2個選項卡,都帶有2個RecyclerView,當滾動時它會自動摺疊工具欄。當RecyclerView適合屏幕時,不要摺疊工具欄

我的問題是:我可以禁用工具欄摺疊時,RecyclerView有幾個項目,完全適合屏幕(如在選項卡2)?

我見過很多像CheeseSquare這樣的例子,由Google員工製作,問題仍然存在:即使RecyclerView只有1個項目,工具欄仍然保持滾動狀態。

enter image description here

我想我可以找出是否RecyclerView的第一項是顯示在屏幕上,如果是禁用的工具欄崩潰。前者很容易實現,後者呢?

這是我的佈局:

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

     <android.support.design.widget.AppBarLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:fitsSystemWindows="true" 
      android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      app:layout_scrollFlags="scroll|enterAlwaysCollapsed" 
      android:background="?attr/colorPrimary" 
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> 

     <android.support.design.widget.TabLayout 
      android:id="@+id/tab_layout" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="@color/glucosio_pink" 
      app:tabSelectedTextColor="@android:color/white" 
      app:tabIndicatorColor="@color/glucosio_accent" 
      app:tabTextColor="#80ffffff"/> 
     </android.support.design.widget.AppBarLayout> 

     <android.support.v4.view.ViewPager 
      android:id="@+id/pager" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"/> 

    <android.support.design.widget.FloatingActionButton 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/main_fab" 
     android:layout_margin="16dp" 
     android:onClick="onFabClicked" 
     app:backgroundTint="@color/glucosio_accent" 
     android:src="@drawable/ic_add_black_24dp" 
     android:layout_gravity="bottom|right" 
     /> 
    </android.support.design.widget.CoordinatorLayout> 




+0

你能告訴我你是怎麼創造這個GIF? –

+1

Hi @PratikButani!我在網上找到了gif(https://mzgreen.github.io/2015/06/23/How-to-hideshow-Toolbar-when-list-is-scrolling(part3)/)。順便說一句,你可以使用像https://gifs.com/這樣的服務從YouTube視頻創建一個gif。 –

+0

用你的鏈接傾訴給那個人:)願他會幫助你。謝謝:) https://twitter.com/pratik13butani/status/644355243174526976 –

回答

18

最終解決(感謝米哈爾Z.)

方法來關閉/打開工具欄滾動:

public void turnOffToolbarScrolling() { 
    Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); 
    AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout); 

    //turn off scrolling 
    AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams(); 
    toolbarLayoutParams.setScrollFlags(0); 
    mToolbar.setLayoutParams(toolbarLayoutParams); 

    CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
    appBarLayoutParams.setBehavior(null); 
    appBarLayout.setLayoutParams(appBarLayoutParams); 
} 

public void turnOnToolbarScrolling() { 
    Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); 
    AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout); 

    //turn on scrolling 
    AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams(); 
    toolbarLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); 
    mToolbar.setLayoutParams(toolbarLayoutParams); 

    CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
    appBarLayoutParams.setBehavior(new AppBarLayout.Behavior()); 
    appBarLayout.setLayoutParams(appBarLayoutParams); 
} 


瞭解RecyclerView的最後一項是否在我的片段中可見。
如果是的話,禁用滾動:

public void updateToolbarBehaviour(){ 
    if (mLayoutManager.findLastCompletelyVisibleItemPosition() == items.size()-1) { 
     ((MainActivity) getActivity()).turnOffToolbarScrolling(); 
    } else { 
     ((MainActivity)getActivity()).turnOnToolbarScrolling(); 
    } 
} 
+1

您需要首次使用處理器(使用Handler-Runnable)來調用'updateToolbarBehaviour()'。否則,findLastCompletelyVisibleItemPosition()方法最初返回「-1」。 –

7

您可以檢查是否在RecyclerView的最後一個項目是可見的。如果它不然後關閉滾動以編程方式使用此方法:

  //turn off scrolling 
      AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams(); 
      toolbarLayoutParams.setScrollFlags(0); 
      mToolbar.setLayoutParams(toolbarLayoutParams); 

      CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
      appBarLayoutParams.setBehavior(null); 
      appBarLayout.setLayoutParams(appBarLayoutParams); 
+0

很好,謝謝!我已經用方法和方法更新了我的問題。 –

+0

工作正常,但如果視圖的內容具有app:layout_behavior =「@ string/appbar_scrolling_view_behavior」,並且也具有layout_height =「match_parent」,那麼關閉滾動後內容將不會居中 –

+0

這很適用於禁用滾動,但如果重新啓用相同的不同的片段不會工作,在設置滾動標誌編程。 – pallavi

-1
//turn off scrolling 
AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams(); 
toolbarLayoutParams.setScrollFlags(0); 
mToolbar.setLayoutParams(toolbarLayoutParams); 
2

我參加了一個稍微不同的方法來解決這個問題。

我創建了一個自定義AppBarBehavior,基於單元格禁用其自身。

public class CustomAppBarBehavior extends AppBarLayout.Behavior { 

    private RecyclerView recyclerView; 
    private boolean enabled; 

    public CustomAppBarBehavior() { 
    } 

    public CustomAppBarBehavior(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) { 
     updatedEnabled(); 
     return enabled && super.onInterceptTouchEvent(parent, child, ev); 
    } 

    @Override 
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) { 
     return enabled && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes); 
    } 

    @Override 
    public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) { 
     return enabled && super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); 
    } 

    private void updatedEnabled() { 
     enabled = false; 
     if(recyclerView != null) { 
      RecyclerView.Adapter adapter = recyclerView.getAdapter(); 
      if (adapter != null) { 
       int count = adapter.getItemCount(); 
       RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); 
       if (layoutManager != null) { 
        int lastItem = 0; 
        if (layoutManager instanceof LinearLayoutManager) { 
         LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager; 
         lastItem = Math.abs(linearLayoutManager.findLastCompletelyVisibleItemPosition()); 
        } else if (layoutManager instanceof StaggeredGridLayoutManager) { 
         StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; 
         int[] lastItems = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(new int[staggeredGridLayoutManager.getSpanCount()]); 
         lastItem = Math.abs(lastItems[lastItems.length - 1]); 
        } 
        enabled = lastItem < count - 1; 
       } 
      } 
     } 
    } 

    public void setRecyclerView(RecyclerView recyclerView) { 
     this.recyclerView = recyclerView; 
    } 
} 

然後設置自定義行爲上的應用欄佈局

appBarBehavior = new CustomAppBarBehavior(); 
CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
appBarLayoutParams.setBehavior(appBarBehavior); 
appBarLayout.setLayoutParams(appBarLayoutParams); 

最後的更新RecyclerView的行爲的看法尋呼機頁改變

private ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } 

     @Override 
     public void onPageSelected(final int position) {    
      appBarLayout.setExpanded(true, true); 
      appBarLayout.post(new Runnable() { 
       @Override 
       public void run() { 
        appBarBehavior.setRecyclerView(childFragments.get(position).getRecyclerView()); 
       } 
      }); 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { } 
    }; 

這應該與不斷變化的工作數據集。

+0

真的很有趣。感謝分享。 –

+0

哦,你也需要重置旋轉的recyclerview,同時要記住,視圖尋呼機在被恢復後給出索引0,即使它不是真的在那個頁面上。片段是一種快樂。 –

6

RecyclerView現在(自版本23.2起)支持wrap_content。只需使用wrap_content作爲高度。

+0

不幸的是,當我用'SwipeRefreshLayout'包裝'RecyclerView'時,它不適用於我。 –

+0

這對我使用NestedScrollView工作。謝謝! – nope4561759

-1

剛剛從

app:layout_scrollFlags="scroll|enterAlways" 

刪除滾動所以應該

app:layout_scrollFlags="enterAlways" 
+1

這完全鎖定CollapsingToolbarLayout滾動... –

相關問題