【问题标题】:Floating Action Button not showing fully inside a fragment浮动操作按钮未在片段内完全显示
【发布时间】:2015-08-24 05:54:04
【问题描述】:

我在片段中使用 FAB 按钮和 RecyclerView。这个 Fragment 是 TabViewPager 的一个实例。我遇到了 FAB 按钮的问题。我已将 RecyclerView 和 fab 按钮放置在 FrameLayout 内,FAB 按钮位于右下角。现在我面临的问题是 FAB 按钮不完全可见。它的一半部分被隐藏,如下面的屏幕截图所示。谁能帮我解决这个问题。提前致谢。

注意: FAB 在滚动后会正确对齐。只有在理想情况下才会出现问题(在滚动完成之前)。

fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

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

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="10dp"
        app:backgroundTint="@color/red"
        android:src="@drawable/ic_done"/>
</FrameLayout>

tabviewpagerlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<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/appBarLayout"
        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>

【问题讨论】:

  • 注意,我没有使用新的设计库...但是...可能是FAB默认为关闭屏幕。尝试删除它的边距。当您滚动(向上?)时,FAB 应该会出现。向下滚动应将其删除。这样 FAB 就不会妨碍您在 RecyclerView 上的最后一行。在这种情况下,会有一个辅助功能可以让 FAB 随意出现。
  • 实际上在滚动期间它工作正常。但是当它处于理想模式时,就会出现问题,就像上面附上的屏幕截图一样。看起来很别扭。
  • 为什么不试试RelativeLayout 而不是FrameLayout
  • 我也通过分配 alignparent_bottom 和 alignparent_right="true" 尝试使用 RelativeLayout。也是无奈。表现得一样。我认为问题在于 CoordinatorLayout 属性
  • 我面临同样的问题。在我的情况下,这是由于工具栏上的 layout_scrollFlags 属性引起的。当此属性设置为“scroll|enterAlways”时,您会注意到视图会变大一点,以便能够向上滚动并隐藏工具栏。将其设为静态将“解决”此问题。如果您确实找到了解决方法,请告诉我们。

标签: android android-fragments floating-action-button androiddesignsupport android-coordinatorlayout


【解决方案1】:

即使在 2021 年也有很多问题。我的解决方法

  • 将 Floating Bar 放置到主 Activity 布局中 - 这样它就会显示在整个应用程序/所有片段(我知道)中的正确位置。
  • 然后您可以通过编程方式将其隐藏在您不需要的片段中。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,要求在片段中显示 FAB。我所做的只是从工具栏中删除了该行

    app:layout_scrollFlags="scroll|enterAlways"
    

    你可以检查我的布局

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".MainActivity">
    
        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="@dimen/appbar_padding_top"
            android:background="@color/white"
            app:elevation="0dp"
            android:elevation="0dp"
            >
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar_main"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_weight="1"
                android:background="@color/white"
                app:title="@string/app_name">
    
            </android.support.v7.widget.Toolbar>
    
            <android.support.design.widget.TabLayout
                android:id="@+id/tabs_main"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                >
    
    
            </android.support.design.widget.TabLayout>
    
        </android.support.design.widget.AppBarLayout>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
    </android.support.design.widget.CoordinatorLayout>
    

    【讨论】:

      【解决方案3】:

      这个解决方案对我有用。使用以下代码创建一个名为 CustomBehavior 的新类:

      public class CustomBehavior extends CoordinatorLayout.Behavior<ViewPager> {
      
      private int mActionBarHeight;
      
      public CustomBehavior(Context context, AttributeSet attributeSet) {
          super(context, attributeSet);
          init(context);
      }
      
      public CustomBehavior(Context context) {
          init(context);
      }
      
      private void init(Context context) {
          TypedValue tv = new TypedValue();
          if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
              mActionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
          }
      }
      
      @Override
      public boolean layoutDependsOn(CoordinatorLayout parent, ViewPager child, View dependency) {
          return dependency instanceof AppBarLayout;
      }
      
      public boolean onDependentViewChanged(CoordinatorLayout parent, ViewPager child, View dependency) {
          offsetChildAsNeeded(parent, child, dependency);
          return false;
      }
      
      private void offsetChildAsNeeded(CoordinatorLayout parent, View child, View dependency) {
          if (child instanceof ViewPager) {
              ViewPager viewPager = (ViewPager) child;
              View list = viewPager.findViewById(R.id.recycler_view);
              if (list != null) {
                  final CoordinatorLayout.Behavior behavior =
                          ((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
                  if (behavior instanceof AppBarLayout.Behavior) {
                      final AppBarLayout.Behavior ablBehavior = (AppBarLayout.Behavior) behavior;
                      AppBarLayout appBarLayout = (AppBarLayout) dependency;
                      ViewCompat.setTranslationY(list, ablBehavior.getTopAndBottomOffset()
                              + appBarLayout.getTotalScrollRange()
                              + mActionBarHeight);
                  }
              }
          }
      }
      

      }

      现在,将自定义行为类分配给 xml 文件中的 viewpager 小部件

      <android.support.v4.view.ViewPager
          android:id="@+id/viewpager"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          app:layout_behavior="yourpackage.CustomBehavior"
          />
      

      【讨论】:

      • 我赞成这个答案,因为我认为它是最接近正确答案的答案。但是,我注意到我的回收站视图的第一项从工具栏后面开始。一旦我触摸列表进行滚动,CustomBehavior 类就会启动并在其适当的位置显示第一行。
      【解决方案4】:

      我面临着与视图寻呼机 1st Fragment FAB 按钮显示在屏幕下方并在滚动显示时相同的问题。 但经过一番调查后发现自己写了

      app:layout_behavior="@string/appbar_scrolling_view_behavior"
      

      在 CoordinatorLayout 的 ViewPager 中。所以去掉这个滚动行为后,FAB 位置问题就解决了。

      请检查我的实现是否正常工作:

      <?xml version="1.0" encoding="utf-8"?>
      
      <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:layout_scrollFlags="scroll|enterAlways"
                  app:popupTheme="@style/AppTheme.PopupOverlay">
      
                  <LinearLayout
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:orientation="vertical">
      
                      <TextView
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content"
                          android:gravity="center_horizontal"
                          android:text="@string/app_name"
                          android:textColor="@color/textPrimary"
                          android:textSize="18sp" />
      
                      <TextView
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content"
                          android:gravity="center_horizontal"
                          android:text="@string/str_toolbar_subtittle"
                          android:textColor="@color/textPrimary"
                          android:textSize="14sp" />
                  </LinearLayout>
              </android.support.v7.widget.Toolbar>
      
              <android.support.design.widget.TabLayout
                  android:id="@+id/tabs"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_gravity="bottom"
                  android:background="?attr/colorPrimary"
                  app:tabGravity="fill"
                  app:tabIndicatorColor="@color/colorAccent"
                  app:tabSelectedTextColor="@color/errorColor"
                  app:tabTextColor="@color/white" />
      
          </android.support.design.widget.AppBarLayout>
      
          <android.support.v4.view.ViewPager
              android:id="@+id/viewpager"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:layout_below="@+id/app_bar" />
      
      </android.support.design.widget.CoordinatorLayout>
      

      【讨论】:

      • 就我而言,这并没有解决问题。在我注意到我的列表的第一项(viewpager 中的片段包含一个回收器视图)之前,它看起来还不错,在 appbar 下。
      • 这不是解决方案兄弟。如果我们删除这个 "app:layout_behavior="@string/appbar_scrolling_view_behavior" " 行为动作栏隐藏行为将不再存在。
      【解决方案5】:

      可能有点晚了,但对我来说,最好的选择似乎是创建另一个片段,其中包含带有您的内容和浮动按钮的片段。此代码在我的应用程序中运行良好:

      <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context="domain.ItemsFragment">
      
      
          <fragment
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:name="com.lucyapp.client.ItemFragment"
              android:id="@+id/fragment"
              tools:layout="@layout/fragment_item_list" />
      
          <android.support.design.widget.FloatingActionButton
              android:id="@+id/fab"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="bottom|end"
              android:layout_margin="@dimen/fab_margin"
              android:src="@android:drawable/ic_dialog_email" />
      
      </FrameLayout>
      

      【讨论】:

        【解决方案6】:
        1. 我遇到了同样的问题,即 FloatingActionButton 完全不可见,并且它在底部的屏幕之外。当我向下滚动时,它会出现。
        2. 此外,选项卡在向下滚动时会被隐藏,但我希望它们始终可见,因此我通过删除 app:layout_scrollFlags="scroll|enterAlways" 来修复它。感谢 JDev how to avoid hiding the tabs when scrolled down?
          这也解决了 FloatingActionButton 问题,现在可见。

        【讨论】:

        • 是的,这解决了晶圆厂问题。现在 FAB 的事情有更好的解决方案吗?
        • 我没有看到任何东西。我试图在 recyclerview 的底部保留填充或边距,从而使工厂升起,但留下了一个空白空间,这又是丑陋的。
        • @cgr 这解决了 fab 问题,但现在工具栏无法滚动。
        【解决方案7】:

        我刚刚遇到了同样的问题。不幸的是,我没有给你答案,但有一些附加点。

        不是按钮被按下,而是整个片段被按下。到目前为止我还没有测试它,但我想,如果有一种方法可以让你看到片段页面的大小,你会看到它不会像它应该的那样在屏幕底部结束。

        对于可能的解决方案,我正在考虑在底部添加大小为“?attr/actionBarSize”的填充。

        我会测试一下,完成后回帖

        更新: 因为我使用了 80 dp 的边框,所以得到一个 screen shot(我没有 10 声望来发布屏幕截图)

        解决方法:

        <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/rootLayout"
                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:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        
                    <include
                        layout="@layout/toolbar"/>
        
                </android.support.design.widget.AppBarLayout>
        
                <FrameLayout
                    android:id="@+id/fragment_root"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@drawable/border"
                    android:layout_marginTop="?attr/actionBarSize"
                    >
                    <!--android:paddingBottom="?attr/actionBarSize"-->
                    <!--app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@drawable/border"></LinearLayout>
                    <fragment
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:name="com.derek.hianthy.mydiary.ui.BaseFragment"
                        tools:layout="@layout/layout"
                        android:background="@drawable/border"
                        />
        
                </FrameLayout>
                <android.support.design.widget.FloatingActionButton
                    android:id="@+id/fabBtn"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom|right"
                    android:layout_marginBottom="@dimen/fab_margin_bottom"
                    android:layout_marginRight="@dimen/fab_margin_right"
                    android:src="@drawable/ic_action_add"
                    app:borderWidth="0dp"
                    app:fabSize="normal"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentTop="false"
                    android:layout_alignParentLeft="false" />
        
            </android.support.design.widget.CoordinatorLayout>
        

        notic app:layout_behavior="@string/appbar_scrolling_view_behavior" 已被删除。 result

        【讨论】:

        • 谢谢..Material 设计支持库有问题。猜猜它应该在下一个版本中解决。
        • 看看我的新更新,提供可能的解决方法
        【解决方案8】:

        我按照 Gabriele 的建议将 FAB 移至包含活动的地方。您还需要在 onTabSelected 中更新 FAB 的颜色/clickListener:

        public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
        
                ...
        
                setFloatingActionButtonForImagesTab();
        
            }
        
            ...
        
            @Override
            public void onTabSelected(final TabLayout.Tab tab) {
            switch (tab.getPosition()) {
                case 0:
                    setFloatingActionButtonForImagesTab();
                    break;
                case 1:
                    setFloatingActionButtonForMusicTab();
                    break;
                case 2:
                    setFloatingActionButtonForVideoTab();
                    break;
                }
            }
        
            ...
        
        }
        

        然后在设置函数中设置颜色并点击监听器:

        private void setFloatingActionButtonForImagesTab() {
            myViewPager.setCurrentItem(0);
            floatingActionButton.setBackgroundTintList(getResources().getColorStateList(R.color.purple));
            floatingActionButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Snackbar.make(coordinatorLayout, "images", Snackbar.LENGTH_LONG)
                        .show();
                }
            });
        }
        

        记下上面对setCurrentItem 的调用。现在你需要实现TabLayout.OnTabSelectedListener

        【讨论】:

          【解决方案9】:

          无论选择什么选项卡,都必须显示/隐藏 FAB,这不是一个可接受的解决方案。我已经尝试了每种布局组合,但将 FAB 移动到活动布局是唯一可行的解​​决方案。但是,如果您只需要一个选项卡中的按钮怎么办?这是现在唯一可行的方法,但我期待更新设计库,因为这个版本太有问题了。无论如何,底线是 FAB 必须是 CoordinatorLayout 的直接后代,所以它不会被折叠的 Toolbar 向下推...

          【讨论】:

          • 仅此而已,但嵌套的 CoordinatorLayout 似乎也不起作用。
          【解决方案10】:

          您应该将您的 FAB 移动到 CoordinatorLayout 中。 像这样的:

          <android.support.design.widget.CoordinatorLayout>
          
              <android.support.design.widget.AppBarLayout>
          
                  <android.support.v7.widget.Toolbar
                      app:layout_scrollFlags="scroll|enterAlways" />
          
                  <android.support.design.widget.TabLayout/>
          
              </android.support.design.widget.AppBarLayout>
          
              <android.support.v4.view.ViewPager
                  app:layout_behavior="@string/appbar_scrolling_view_behavior" />
          
              <android.support.design.widget.FloatingActionButton
                  android:id="@+id/fab"
                  android:layout_gravity="end|bottom"/>
          
          </android.support.design.widget.CoordinatorLayout>
          

          那么就可以这样在viewPager里面添加RecyclerView了:

          Adapter adapter = new Adapter(getSupportFragmentManager());
          adapter.addFragment(new RecyclerViewFragment(), "Tab1");
          viewPager.setAdapter(adapter);
          

          RecyclerViewFragment 布局在哪里:

           <android.support.v7.widget.RecyclerView
                  xmlns:android="http://schemas.android.com/apk/res/android"
                  android:id="@+id/recyclerView"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"/>
          

          【讨论】:

          • 是的,我同意。但我的要求是在片段中显示 FAB。
          • @Chandru 你在片段里面是什么意思?
          • 我有一个包含三个选项卡(即图像、音乐、视频)的 MainActivity。对于每个选项卡,我都有不同的片段,例如 ImagesFragment、MusicFragment、VideoFragment。所以我的要求是在每个片段中显示单独的 FAB 按钮。
          • @Chandru 您应该使用单个 FAB。如果您需要不同的颜色或不同的操作,您可以在 Fragment 的 onCreateView 中分配颜色和操作。
          • @Chandru 在很多方面。例如 getActivity().findById(R.id.fab) 在您的 OnCreateView 方法中。
          猜你喜欢
          • 2016-11-09
          • 1970-01-01
          • 1970-01-01
          • 2022-06-25
          • 1970-01-01
          • 1970-01-01
          • 2015-12-09
          • 2020-12-18
          • 1970-01-01
          相关资源
          最近更新 更多