浮动操作按钮出现在导航抽屉上方

Floating Action Button appears over Navigation Drawer

所以我使用 https://github.com/neokree/MaterialNavigationDrawer for my navigation drawer and https://gist.github.com/Jogan/9def6110edf3247825c9 作为我的 FAB 实现。当我打开导航抽屉时,它没有覆盖 FAB,按钮出现在它上面。我想避免隐藏按钮并将其显示在抽屉 open/close 上,因为这会让人分心。有想法该怎么解决这个吗?

编辑: 我正在以编程方式添加 FAB,执行以下操作:

fabButton = new FloatingActionButton.Builder(this)
            .withDrawable(getResources().getDrawable(R.drawable.ic_action_edit))
            .withButtonColor(0xFF2196F3)
            .withGravity(Gravity.BOTTOM | Gravity.END)
            .withMargins(0, 0, 16, 16)
            .create();

更改片段的声明并不能解决问题。我上面链接的 Nav Bar 实现需要 activity 从 MaterialNavigationDrawer 类扩展,它可能首先绘制 Nav Drawer,而按钮始终放在最后。有没有办法以编程方式强制元素排序?

当导航抽屉打开时您会看到 FAB,因为此 FAB 实现将 FAB 添加到内容视图 (android.R.id.content)。根据导航抽屉的实现,它们似乎在视图层次结构中处于同一级别。

如果您不想切换到不同的 FAB 实现。使用 onDrawerSlide(View drawerView, float offset) 并在打开抽屉时更改 FAB alpha。您也可以在 onDrawerClose()onDrawerOpen() 方法中切换其可见性。

编辑:

@Override
public void onDrawerSlide(View drawerView, float offset){
   fabButton.setAlpha(offset);
}

我找到了一个简洁的解决方案,它不涉及 alpha 或在抽屉打开或关闭时切换按钮(这让它看起来像延迟)。以编程方式,您可以修改按钮的结束边距,以便它在抽屉的偏移量更改时从 activity 的 window 过渡。

所以首先,在 onDrawerSlide 方法之外,您必须使用以下代码获取 FAB 的布局参数(取决于按钮所在的布局,在我的例子中,它是 FrameLayout ):

final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) fab.getLayoutParams();

明白我是根据一个简单的数学线性方程来做的:y = mx + n,而'y'是margin,'m'是斜率(你可以修改) , 'x' 是 slideOffset 而 'n' 是 default/original 边距 (16dp)。这就是您如何将默认边距和斜率分配给变量作为像素,同时尊重显示密度的丰富性:

int density = (int) Resources.getSystem().getDisplayMetrics().density;
final int defaultMargin = 16 * density;
final int slope = -100 * density;

然后,在 onDrawerSlide 中,执​​行以下操作:

params.setMarginEnd((int) (slope * slideOffset + defaultMargin));
fab.setLayoutParams(params);

如果这对您不起作用,请尝试在构建按钮时设置按钮的 marginEnd,或者像这样设置布局参数的边距(尽管您必须检查 marginEnd是右还是左):

params.setMargins(int left, int top, int right, int bottom);

希望对您有所帮助。这是我的第一个回答,所以我希望你不会对此有太多的抱怨。

这是对我有用的替代解决方案。 假设你想在 yourlayout.xml 中添加 FAB。 现在在 yourlayout.xml

中创建一个框架布局
    <FrameLayout
        android:id="@+id/myframelayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

现在在FloatingActionButton.java替换方法

public FloatingActionButton create() {
  ...
  ViewGroup root = (ViewGroup) activity.findViewById(android.R.id.content);
  root.addView(button, params);
  return button;
}

 public FloatingActionButton create(FrameLayout framelayout) {
  ...
  framelayout.addView(button, params);
  return button;
}

现在像这样更改 FAB 声明。

FrameLayout yourframelayout = (FrameLayout)findViewById(R.id.myframelayout);

fabButton = new FloatingActionButton.Builder(this)
        .withDrawable(getResources().getDrawable(R.drawable.ic_action_edit))
        .withButtonColor(0xFF2196F3)
        .withGravity(Gravity.BOTTOM | Gravity.END)
        .withMargins(0, 0, 16, 16)
        .create(yourframelayout);

就是这样!!

我正在更新 Nikola Despotoski 解决方案:

所以你必须 disable/hide fab 在设置 alpha 之后,所以如果任何时候用户点击显示 fab 的地方,那么什么都不会发生。

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open,
                R.string.drawer_close) {
   public void onDrawerClosed(View view) {
               // Visible/Enable the FAB
   }

   public void onDrawerOpened(View drawerView) {
               // Hide/Disable the FAB
   }

   @Override
   public void onDrawerSlide(View drawerView, float slideOffset) {
                // invert the slideOffset value
                fab.setAlpha(1-slideOffset);
   }
};