【问题标题】:Toolbar in AppBarLayout is scrollable although RecyclerView has not enough content to scrollAppBarLayout 中的工具栏是可滚动的,尽管 RecyclerView 没有足够的内容可以滚动
【发布时间】:2015-11-30 15:19:18
【问题描述】:

AppBarLayout 中的工具栏是否真的可以滚动,尽管带有“appbar_scrolling_view_behavior”的主容器没有足够的内容来真正滚动?

到目前为止我测试过的内容:
当我使用 NestedScrollView(带有“wrap_content”属性)作为主容器并使用 TextView 作为子容器时,AppBarLayout 可以正常工作并且不会滚动。

但是,当我使用只有几个条目和“wrap_content”属性的 RecyclerView(这样就不需要滚动)时,AppBarLayout 中的工具栏是可滚动的,即使 RecyclerView 从未收到滚动事件(经过测试使用 OnScrollChangeListener)。

这是我的布局代码:

<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/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:theme="@style/ToolbarStyle" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

工具栏可滚动的效果如下:

我还找到了一种处理此问题的方法,方法是检查所有 RecyclerView 项目是否可见并使用 RecyclerView 的 setNestedScrollingEnabled() 方法。
尽管如此,对我来说,它似乎更像是一个错误。有什么意见吗? :D

编辑 #1:

对于可能对我当前的解决方案感兴趣的人,我不得不将 setNestedScrollingEnabled() 逻辑放在 Handler 的 postDelayed() 方法中,延迟 5 毫秒,因为 LayoutManager 在调用方法时总是返回 -1找出第一个和最后一个项目是否可见。
我在 onStart() 方法中使用此代码(在我的 RecyclerView 初始化之后)以及每次 RecyclerView 的内容更改发生后。

final LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //no items in the RecyclerView
        if (mRecyclerView.getAdapter().getItemCount() == 0)
            mRecyclerView.setNestedScrollingEnabled(false);
        //if the first and the last item is visible
        else if (layoutManager.findFirstCompletelyVisibleItemPosition() == 0
                && layoutManager.findLastCompletelyVisibleItemPosition() == mRecyclerView.getAdapter().getItemCount() - 1)
            mRecyclerView.setNestedScrollingEnabled(false);
        else
            mRecyclerView.setNestedScrollingEnabled(true);
    }
}, 5);

编辑 #2:

我刚刚试用了一个新应用程序,似乎这种(意外)行为已在支持库版本 23.3.0(或更早版本)中得到修复。因此,不再需要解决方法!

【问题讨论】:

  • 我认为这是有意的。这已经被问过很多次了,如果这是一个错误,他们之前会修复它 - 设计库不再那么年轻了。
  • 好的,谢谢您的回答。由于我自己没有找到提到的答案/讨论,请您至少发布一个来源。
  • 这不是bug,viewGroup中的所有事件都是这样处理的。因为您的 recyclerview 是 coordinatorLayout 的子级,所以无论何时生成事件,都会首先检查父级,如果父级不感兴趣,则将其传递给子级。
  • 我在 Material Design 规范中没有找到任何与此相关的参考资料,但基于 Inbox by GmailGoogle Play (我的愿望清单)目前有效,如果有足够的内容可以滚动,正确的行为似乎是只滚动应用栏。

标签: android android-xml android-coordinatorlayout android-appbarlayout


【解决方案1】:

我想对 user3623735 的回答补充一点。以下代码绝对不正确。

// Find out if RecyclerView are scrollable, delay required
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (rv.canScrollVertically(DOWN) || rv.canScrollVertically(UP)) {
                controller.enableScroll();
            } else {
                controller.disableScroll();
            }
        }
    }, 100);

即使它有效 - 它并不涵盖所有情况。绝对不能保证一个数据会在 100 毫秒内显示出来,并且数据在使用它的过程中可以拉伸视图的高度,不仅在 onCreateView 方法中。这就是为什么你应该使用下一个代码并跟踪视图高度的变化:

view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            if(bottom != oldBottom)
            {
                mActivity.setScrollEnabled(view.canScrollVertically(0) || view.canScrollVertically(1));
            }
        }
    });

而且不需要创建两个单独的方法来控制滚动状态,你应该使用一个 setScrollEnabled 方法:

public void setScrollEnabled(boolean enabled) {
    final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams)
            mToolbar.getLayoutParams();

    params.setScrollFlags(enabled ?
            AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS : 0);

    mToolbar.setLayoutParams(params);
}

【讨论】:

    【解决方案2】:

    所以,正确的信用,这个答案几乎为我解决了它https://stackoverflow.com/a/32923226/5050087。但是因为当你实际上有一个可滚动的回收视图并且它的最后一个项目是可见的时它没有显示工具栏(它不会在第一次向上滚动时显示工具栏),我决定修改它并对其进行调整以更容易实现和动态适配器。

    首先,您必须为您的应用栏创建自定义布局行为:

    public class ToolbarBehavior extends AppBarLayout.Behavior{
    
    private boolean scrollableRecyclerView = false;
    private int count;
    
    public ToolbarBehavior() {
    }
    
    public ToolbarBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
        return scrollableRecyclerView && super.onInterceptTouchEvent(parent, child, ev);
    }
    
    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) {
        updatedScrollable(directTargetChild);
        return scrollableRecyclerView && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type);
    }
    
    @Override
    public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) {
        return scrollableRecyclerView && super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
    }
    
    private void updatedScrollable(View directTargetChild) {
        if (directTargetChild instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) directTargetChild;
            RecyclerView.Adapter adapter = recyclerView.getAdapter();
            if (adapter != null) {
                if (adapter.getItemCount()!= count) {
                    scrollableRecyclerView = false;
                    count = adapter.getItemCount();
                    RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                    if (layoutManager != null) {
                        int lastVisibleItem = 0;
                        if (layoutManager instanceof LinearLayoutManager) {
                            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
                            lastVisibleItem = Math.abs(linearLayoutManager.findLastCompletelyVisibleItemPosition());
                        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                            StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
                            int[] lastItems = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(new int[staggeredGridLayoutManager.getSpanCount()]);
                            lastVisibleItem = Math.abs(lastItems[lastItems.length - 1]);
                        }
                        scrollableRecyclerView = lastVisibleItem < count - 1;
                    }
                }
            }
        } else scrollableRecyclerView = true;
      }
    }
    

    然后,您只需在布局文件中为您的 appbar 定义此行为:

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        app:layout_behavior="com.yourappname.whateverdir.ToolbarBehavior"
        >
    

    我还没有测试过它的屏幕旋转,所以如果它像这样工作,请告诉我。我想它应该可以工作,因为我认为在旋转发生时不会保存 count 变量,但如果没有,请告诉我。

    这对我来说是最简单、最干净的实现,尽情享受吧。

    【讨论】:

    • 我认为鉴于问题中的布局,您应该将该方法称为updatedScrollable(target),因为RecyclerView 不是AppBarLayout. 的直接子代
    • 它实际上是对 CoordinatorLayout 的引用,它是父级 ;)。
    【解决方案3】:

    谢谢,我创建了一个 RecyclerView 的自定义类,但关键仍在使用setNestedScrollingEnabled()。对我来说效果很好。

    public class RecyclerViewCustom extends RecyclerView implements ViewTreeObserver.OnGlobalLayoutListener
    {
        public RecyclerViewCustom(Context context)
        {
            super(context);
        }
    
        public RecyclerViewCustom(Context context, @Nullable AttributeSet attrs)
        {
            super(context, attrs);
        }
    
        public RecyclerViewCustom(Context context, @Nullable AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
        }
    
        /**
         *  This supports scrolling when using RecyclerView with AppbarLayout
         *  Basically RecyclerView should not be scrollable when there's no data or the last item is visible
         *
         *  Call this method after Adapter#updateData() get called
         */
        public void addOnGlobalLayoutListener()
        {
            this.getViewTreeObserver().addOnGlobalLayoutListener(this);
        }
    
        @Override
        public void onGlobalLayout()
        {
            // If the last item is visible or there's no data, the RecyclerView should not be scrollable
            RecyclerView.LayoutManager layoutManager = getLayoutManager();
            final RecyclerView.Adapter adapter = getAdapter();
            if (adapter == null || adapter.getItemCount() <= 0 || layoutManager == null)
            {
                setNestedScrollingEnabled(false);
            }
            else
            {
                int lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
                boolean isLastItemVisible = lastVisibleItemPosition == adapter.getItemCount() - 1;
                setNestedScrollingEnabled(!isLastItemVisible);
            }
    
            unregisterGlobalLayoutListener();
        }
    
        private void unregisterGlobalLayoutListener()
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            {
                getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
            else
            {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      编辑 2:

      事实证明,当 RecyclerView 不可滚动时,确保 Toolbar 不可滚动的唯一方法是以编程方式设置 setScrollFlags,这需要检查 RecyclerView 是否可滚动。每次修改适配器时都必须进行此检查。

      与Activity通信的接口:

      public interface LayoutController {
          void enableScroll();
          void disableScroll();
      }
      

      主活动:

      public class MainActivity extends AppCompatActivity implements 
          LayoutController {
      
          private CollapsingToolbarLayout collapsingToolbarLayout;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
              setSupportActionBar(toolbar);
      
              collapsingToolbarLayout = 
                    (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
      
              final FragmentManager manager = getSupportFragmentManager();
              final Fragment fragment = new CheeseListFragment();
              manager.beginTransaction()
                      .replace(R.id.root_content, fragment)
                      .commit();
          }
      
          @Override
          public void enableScroll() {
              final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams)
                                        collapsingToolbarLayout.getLayoutParams();
              params.setScrollFlags(
                      AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL 
                      | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS
              );
              collapsingToolbarLayout.setLayoutParams(params);
          }
      
          @Override
          public void disableScroll() {
              final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams)
                                        collapsingToolbarLayout.getLayoutParams();
              params.setScrollFlags(0);
              collapsingToolbarLayout.setLayoutParams(params);
          }
      }
      

      activity_main.xml:

      <android.support.v4.widget.DrawerLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/drawer_layout"
          android:layout_height="match_parent"
          android:layout_width="match_parent"
          android:fitsSystemWindows="true">
      
          <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/main_content"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
      
              <android.support.design.widget.AppBarLayout
                  android:id="@+id/appbar"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
      
                  <android.support.design.widget.CollapsingToolbarLayout
                      android:id="@+id/collapsing_toolbar"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:fitsSystemWindows="true"
                      app:contentScrim="?attr/colorPrimary">
      
                      <android.support.v7.widget.Toolbar
                          android:id="@+id/toolbar"
                          android:layout_width="match_parent"
                          android:layout_height="?attr/actionBarSize"
                          android:background="?attr/colorPrimary"
                          app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
      
                  </android.support.design.widget.CollapsingToolbarLayout>
      
              </android.support.design.widget.AppBarLayout>
      
              <FrameLayout
                  android:id="@+id/root_content"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:layout_gravity="fill_vertical"
                  app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
      
          </android.support.design.widget.CoordinatorLayout>
      
      </android.support.v4.widget.DrawerLayout>
      

      测试片段:

      public class CheeseListFragment extends Fragment {
      
          private static final int DOWN = 1;
          private static final int UP = 0;
      
          private LayoutController controller;
          private RecyclerView rv;
      
          @Override
          public void onAttach(Context context) {
              super.onAttach(context);
      
              try {
                  controller = (MainActivity) getActivity();
              } catch (ClassCastException e) {
                  throw new RuntimeException(getActivity().getLocalClassName()
                          + "must implement controller.", e);
              }
          }
      
          @Nullable
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
              rv = (RecyclerView) inflater.inflate(
                      R.layout.fragment_cheese_list, container, false);
              setupRecyclerView(rv);
      
              // Find out if RecyclerView are scrollable, delay required
              final Handler handler = new Handler();
              handler.postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      if (rv.canScrollVertically(DOWN) || rv.canScrollVertically(UP)) {
                          controller.enableScroll();
                      } else {
                          controller.disableScroll();
                      }
                  }
              }, 100);
      
              return rv;
          }
      
          private void setupRecyclerView(RecyclerView recyclerView) {
              final LinearLayoutManager layoutManager = new LinearLayoutManager(recyclerView.getContext());
      
              recyclerView.setLayoutManager(layoutManager);
      
              final SimpleStringRecyclerViewAdapter adapter =
                      new SimpleStringRecyclerViewAdapter(
                              getActivity(),
                              // Test ToolBar scroll
                              getRandomList(/* with enough items to scroll */)
                              // Test ToolBar pin
                              getRandomList(/* with only 3 items*/)
                      );
      
              recyclerView.setAdapter(adapter);
          }
      }
      

      来源:

      编辑:

      您应该使用 CollapsingToolbarLayout 来控制行为。

      将 Toolbar 直接添加到 AppBarLayout 可以让您访问 enterAlwaysCollapsed 和 exitUntilCollapsed 滚动标志,但不能详细控制不同元素对折叠的反应。 [...] 设置使用 CollapsingToolbarLayout 的 app:layout_collapseMode="pin" 来确保工具栏本身在视图折叠时保持固定在屏幕顶部。http://android-developers.blogspot.com.tr/2015/05/android-design-support-library.html

      <android.support.design.widget.CollapsingToolbarLayout
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              app:layout_scrollFlags="scroll|exitUntilCollapsed">
      
          <android.support.v7.widget.Toolbar
              android:id="@+id/drawer_toolbar"
              android:layout_width="match_parent"
              android:layout_height="?attr/actionBarSize"
              app:layout_collapseMode="pin"/>
      
      </android.support.design.widget.CollapsingToolbarLayout>
      

      添加

      app:layout_collapseMode="pin"
      

      到您的 xml 工具栏。

          <android.support.v7.widget.Toolbar
              android:id="@+id/toolbar"
              android:layout_width="match_parent"
              android:layout_height="?attr/actionBarSize"
              android:background="?attr/colorPrimary"
              app:layout_scrollFlags="scroll|enterAlways"
              app:layout_collapseMode="pin"
              app:theme="@style/ToolbarStyle" />
      

      【讨论】:

      • 它对我不起作用。你测试过吗?我想没有。
      • 是的,我在自己的应用程序上使用它。但我只是注意到了我认为的不同。请参阅我的编辑。您应该使用 CollapsingToolbarLayout 包装 Toolbar 并在该视图上设置 scrollFlags,并确保 Toolbar 设置为 pin。
      • 嘿,首先,很抱歉完全误解了您正在尝试做的事情并通过提供错误的答案来浪费您的时间。其次,请检查我的edit2,它完全符合您的要求。如果您有任何问题,请告诉我。
      • 整体思路是有道理的,但是有一个问题。如果在 占据整个 CoordinatorLayout 垂直空间时 recyclerview 不会滚动,但在 占据 AppBarLayout + CollapsingToolbarLayout 留下的所有空间时会滚动,这会中断:RecyclerView 将在其中正常滚动剩余空间,但 AppBarLayout 不会折叠。为了解决这个问题,我们应该以某种方式检查“当 CollapsingToolbarLayout 完全展开时,是否会在剩余的垂直空间内垂直滚动”。
      【解决方案5】:

      我已经使用我自己的 Behavior 类实现了它,该类可能附加到 AppBarLayout:

      public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior {
      
      private RecyclerView recyclerView;
      private int additionalHeight;
      
      public CustomAppBarLayoutBehavior(RecyclerView recyclerView, int additionalHeight) {
          this.recyclerView = recyclerView;
          this.additionalHeight = additionalHeight;
      }
      
      public boolean isRecyclerViewScrollable(RecyclerView recyclerView) {
          return recyclerView.computeHorizontalScrollRange() > recyclerView.getWidth() || recyclerView.computeVerticalScrollRange() > (recyclerView.getHeight() - additionalHeight);
      }
      
      @Override
      public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
          if (isRecyclerViewScrollable(mRecyclerView)) {
              return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
          }
          return false;
      }
      

      }

      以下是如何设置此行为的代码:

      final View appBarLayout = ((DrawerActivity) getActivity()).getAppBarLayoutView();
      CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
      layoutParams.setBehavior(new AppBarLayoutNoEmptyScrollBehavior(recyclerView, getResources().getDimensionPixelSize(R.dimen.control_bar_height)));
      

      【讨论】:

        【解决方案6】:

        LayoutManager 子类中的类似内容似乎会导致所需的行为:

        @Override
        public boolean canScrollVertically() {
            int firstCompletelyVisibleItemPosition = findFirstCompletelyVisibleItemPosition();
            if (firstCompletelyVisibleItemPosition == RecyclerView.NO_POSITION) return false;
        
            int lastCompletelyVisibleItemPosition = findLastCompletelyVisibleItemPosition();
            if (lastCompletelyVisibleItemPosition == RecyclerView.NO_POSITION) return false;
        
            if (firstCompletelyVisibleItemPosition == 0 &&
                    lastCompletelyVisibleItemPosition == getItemCount() - 1)
                return false;
        
            return super.canScrollVertically();
        }
        

        canScrollVertically() 的文档说:

        /**
         * Query if vertical scrolling is currently supported. The default implementation
         * returns false.
         *
         * @return True if this LayoutManager can scroll the current contents vertically
         */
        

        注意“可以垂直滚动当前内容”的措辞,我认为这意味着当前状态应该由返回值反映。

        但是,通过 v7 recyclerview 库 (23.1.1) 提供的任何LayoutManager 子类都没有做到这一点,这让我有点犹豫它是否是一个正确的解决方案;除了本问题中讨论的情况之外,它可能会在其他情况下造成不良影响。

        【讨论】:

        • 这里的一个问题是,如果在滚动应用栏后删除了之前填满屏幕的项目,那么应用栏将卡在屏幕外,因为AppBarLayout.Behavior 将返回@ 987654327@ 在onStartNestedScroll 中,因此不会收到对处理应用栏滚动的onNested[Pre]Scrolll 方法的任何调用。原因是 RecyclerView 仅在其 LayoutManager 表示 canScrollVertically 时才添加 SCROLL_AXIS_VERTICAL 标志。
        【解决方案7】:

        这不是错误,viewGroup 中的所有事件都是这样处理的。因为您的 recyclerview 是 coordinatorLayout 的子级,所以无论何时生成事件,都会首先检查父级,如果父级不感兴趣,则将其传递给子级。 见谷歌documentation

        【讨论】:

          【解决方案8】:

          我建议您尝试this 示例,以支持设计库元素。

          这个布局类似于示例中的布局。

          <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/main_content"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
          
              <android.support.design.widget.AppBarLayout
                  android:id="@+id/appbar"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
          
                  <android.support.v7.widget.Toolbar
                      android:id="@+id/toolbar"
                      android:layout_width="match_parent"
                      android:layout_height="?attr/actionBarSize"
                      android:background="?attr/colorPrimary"
                      app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                      app:layout_scrollFlags="scroll|enterAlways" />
          
                  <android.support.design.widget.TabLayout
                      android:id="@+id/tabs"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content" />
          
              </android.support.design.widget.AppBarLayout>
          
              <android.support.v4.view.ViewPager
                  android:id="@+id/viewpager"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  app:layout_behavior="@string/appbar_scrolling_view_behavior" />
          
          </android.support.design.widget.CoordinatorLayout>
          

          【讨论】:

          • 你会启动示例吗?
          • 我测试过,如果你减少RecyclerView中的项目,你会发现这个例子有同样的问题。因此,这是一个错误还是有意为之的问题仍然存在。
          • 请参阅下面关于预期行为的答案。我对建议的项目也有同样的问题:dropbox.com/s/16fep4r7linjtnp/sameproblem.mov?dl=0
          【解决方案9】:

          在你的Toolbar 中删除scroll 标志,只留下enterAlways 标志,你应该得到你想要的效果。为了完整起见,您的布局应如下所示:

          <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/coordinatorLayout"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
          
              <android.support.design.widget.AppBarLayout
                  android:id="@+id/appBarLayout"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content">
          
                  <android.support.v7.widget.Toolbar
                      android:id="@+id/toolbar"
                      android:layout_width="match_parent"
                      android:layout_height="?attr/actionBarSize"
                      android:background="?attr/colorPrimary"
                      app:layout_scrollFlags="enterAlways"
                      app:theme="@style/ToolbarStyle" />
              </android.support.design.widget.AppBarLayout>
          
              <android.support.v7.widget.RecyclerView
                  android:id="@+id/recycler"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  app:layout_behavior="@string/appbar_scrolling_view_behavior" />
          </android.support.design.widget.CoordinatorLayout>
          

          【讨论】:

          • 如果 RecyclerView 有足够的内容,但如果没有足够的内容,我希望工具栏滚动并离开屏幕。如果我删除滚动标志,工具栏根本不会滚动。
          猜你喜欢
          • 1970-01-01
          • 2022-11-16
          • 1970-01-01
          • 2022-09-22
          • 2017-05-31
          • 1970-01-01
          • 1970-01-01
          • 2018-11-02
          • 2015-09-18
          相关资源
          最近更新 更多