Floating Action Button appears over Navigation Drawer

人盡茶涼 提交于 2019-12-04 04:21:05

You see FAB when the navigation drawer is open because this FAB implementation adds FAB to the content view (android.R.id.content). Depending on the navigation drawer implementation they seem to be on same level in the view hierarchy.

If you don't want to switch to different FAB implementation. Use onDrawerSlide(View drawerView, float offset) and change FAB alpha as you open the drawer. Also you could toggle its visibility inside onDrawerClose() or onDrawerOpen() methods too.

Edit:

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

I've found a neat solution that doesn't involve alpha in it or toggling the button when the drawer's opened or closed (which makes it look like a delay). Programmatically, you can modify the button's end margin so that it transitions out of the activity's window while the drawer's offset changes.

So first of all, outside the onDrawerSlide method, you must get the FAB's layout parameters with the following code (depending on the layout the button's in, in my case, it's a FrameLayout):

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

Understand that I'm doing this based on a simple mathematical linear equation: y = mx + n, while 'y' is the margin, 'm' is the slope (you can modify it), 'x' is the slideOffset and 'n' is the default/original margin (16dp). This is how you assign the default margin and the slope to variables as pixels while respecting the abundance of display densities:

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

Then, inside onDrawerSlide, do the following:

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

If this doesn't work for you, try to set the button's marginEnd when building it, or set the margins of the layout's parameters like this (though you would have to check if marginEnd is right or left):

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

I hope this helped. This is my first answer so I hope you won't have much complaints about it.

This is an alternative solution which works for me. Suppose you want to add FAB in yourlayout.xml. Now create a framelayout in yourlayout.xml

    <FrameLayout
        android:id="@+id/myframelayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

Now in FloatingActionButton.java replace the method

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

with

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

Now change the FAB declaration like this.

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);

That's it!!

I am updating Nikola Despotoski solution:

So you have to disable/hide the fab also after setting the alpha so if any time user taps at place where fab is shown then nothing would happen.

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);
   }
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!