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

7
所以我正在使用https://github.com/neokree/MaterialNavigationDrawer作为我的导航抽屉,https://gist.github.com/Jogan/9def6110edf3247825c9作为我的FAB实现。当我打开导航抽屉时,它不会覆盖FAB,并且按钮出现在其上方。我希望避免隐藏按钮并在抽屉打开/关闭时显示它,因为那样会分散注意力。有什么想法如何解决这个问题吗?
编辑: 我通过以下方式以编程方式添加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();

将该声明更改为片段并不能修复它。我上面链接的导航栏实现需要该活动从MaterialNavigationDrawer类扩展,这可能会先绘制Nav抽屉,使按钮始终在最后。有没有办法以编程方式强制元素的顺序?
4个回答

8
当导航抽屉打开时,您会看到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,因为我对它不是很熟悉。 - Phillip Godzin
1
好的,你还有两个选项:修改原始实现以将FAB添加到你的片段布局中,或者在导航抽屉窥视时立即隐藏FAB。请参见我对你关于更改alpha的问题的编辑。 - Nikola Despotoski
实现有助于动画效果。我希望导航抽屉能够覆盖按钮。但问题在于,导航抽屉的实现强制我不能有一个onCreate方法,因此我无法设置内容视图。相反,它会启动固定在抽屉第一部分的片段,因此在那个时候片段的布局不可用。有没有办法改变内容视图中的顺序? - Phillip Godzin
1
实际上,这个实现很好用。不过有一个改变 - 需要设置setAlpha(1-offset),因为当抽屉打开时,按钮需要消失。 - Phillip Godzin
1
这个解决方案非常好,除了我使用了1 - offset之外。然而,当我的抽屉打开并且我旋转设备时,浮动操作按钮不会回来...所以我将浮动操作按钮的透明度值存储为MainActivity中的实例变量,并通过onCreate() / onSaveInstanceState()在Bundle中进行保存/恢复。这修复了方向更改的用例。 - Andy H.
1
解决方案很好,但是它是倒置的。@Andy H的解决方案完全有效。 - Prashant

2
我发现一个不错的解决方案,它不涉及alpha或在抽屉打开或关闭时切换按钮(这会使其看起来像是延迟)。从编程角度来看,您可以修改按钮的结束边距,以便在抽屉偏移更改时将其转出活动窗口。
首先,在onDrawerSlide方法之外,您必须使用以下代码获取FAB的布局参数(取决于按钮所在的布局,在我的情况下,它是一个FrameLayout):
final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) fab.getLayoutParams();

理解我基于一条简单的数学线性方程:y = mx + n,其中 'y' 是边距,'m' 是斜率(您可以修改它),'x' 是 slideOffset,'n' 是默认/原始边距(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);

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


1
这是一种对我有效的替代方案。假设您想在yourlayout.xml中添加FAB。现在在yourlayout.xml中创建一个FrameLayout。
    <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);

就是这样!!


0

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

因此,在设置 alpha 后,您必须禁用/隐藏 fab,以便如果用户在显示 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);
   }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接