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滚动... –

相关问题