Reputation: 15
I want my floating action button to appear when navigation drawer is open and will disappear when navigation drawer is closed, how do I do this? Here is a image for you to see what I am talking about. Here is the image.
Here is my code for the activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawer_layout"
>
<com.google.android.material.navigation.NavigationView
android:id="@+id/drawerNavigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/navigation_drawer_header"
app:menu="@menu/navigation_drawer_menu"
android:fitsSystemWindows="true"
app:insetForeground="@android:color/transparent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingLeft="20dp"
android:paddingBottom="20dp"
android:paddingTop="40dp">
<ImageView
android:id="@+id/logoutNavigationDrawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src ="@drawable/icon_logout"
android:layout_centerVertical="true"
/>
<TextView
android:id="@+id/logoutTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/orangeText"
android:paddingLeft="14dp"
android:textSize="16sp"
android:fontFamily="@font/century_gothic_bold"
android:text="Log out"
android:layout_toEndOf="@+id/logoutNavigationDrawer"
android:layout_toRightOf="@+id/logoutNavigationDrawer"
android:layout_centerVertical="true"/>
</RelativeLayout>
</com.google.android.material.navigation.NavigationView>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/emergencyCallFAB"
android:layout_width="wrap_content"
app:tint="@color/white"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="@drawable/emergency_call_button_round"
app:backgroundTint="@color/red"
android:layout_marginStart="370dp"
android:layout_marginEnd="50dp"
android:layout_marginTop="800dp"
android:layout_marginBottom="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.drawerlayout.widget.DrawerLayout>
Here is my java code in where I implemented the NavigationDrawer
//Setting Emergency Floating Action Button
emergenyCallFABBtn = findViewById(R.id.emergencyCallFAB);
//Will open the menu, once hamburger button has been clicked
hamburgerMenuButton = findViewById(R.id.hamburgerMenuIcon);
hamburgerMenuButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
drawerLayout.openDrawer(GravityCompat.START);
}
});
drawerLayout.setScrimColor(Color.parseColor("#00000000")); // set screen color behind navigation , this is what makes screen behind navigation looks as same color
//NavigationDrawer Function
navigationView.bringToFront();
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(Location.this, drawerLayout,
R.string.navigation_drawer_open, R.string.navigation_drawer_close){
public void onDrawerOpened(View drawerView){
super.onDrawerClosed(drawerView);
emergenyCallFABBtn.setVisibility(View.VISIBLE); // make it visible and bring to front
emergenyCallFABBtn.bringToFront();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
emergenyCallFABBtn.setVisibility(View.VISIBLE);
emergenyCallFABBtn.setAlpha(slideOffset); // makes it visible it animation , as drawer opens button becomes less faded and vice versa in case of close
}
public void onDrawerClosed(View view){
super.onDrawerClosed(view);
emergenyCallFABBtn.setVisibility(View.GONE); // hide button on drawer close
}
};
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
navigationView.setItemIconTintList(null);
navigationView.setNavigationItemSelectedListener(Location.this);
emergenyCallFABBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Location.this, EmergencyCall.class);
startActivity(intent);
Toast.makeText(Location.this, "Clicked on Emergency Call", Toast.LENGTH_SHORT).show();
}
});
Here is my onNavigationItemSelected and my onBackPressed function
//Case switch function for the hamburger menu.
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.homeNavigationDrawer:
Intent homeNavDrawer = new Intent(Location.this, TrackActivity.class);
startActivity(homeNavDrawer);
break;
case R.id.profileNavigationDrawer:
Intent profileNavDrawer = new Intent(Location.this, Profile.class);
startActivity(profileNavDrawer);
break;
case R.id.changeCityNavigationDrawer:
Intent changeCityNavDrawer = new Intent(Location.this, NCR.class);
startActivity(changeCityNavDrawer);
break;
// case R.id.nav_logout:
// try {
// auth.signOut();
// Intent i = new Intent(getApplicationContext(), Location.class);
// startActivity(i);
// // signed out
// } catch (Exception e) {
// // Error handling!
// }
// break;
}
return true;
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (drawerLayout.isDrawerOpen(navigationView)) {
View content = findViewById(R.id.emergencyCallFAB); // find the id of the view you want to check for clicable
int[] contentLocation = new int[2];
content.getLocationOnScreen(contentLocation);
Rect rect = new Rect(contentLocation[0],
contentLocation[1],
contentLocation[0] + content.getWidth(),
contentLocation[1] + content.getHeight());
if ((rect.contains((int) event.getX(), (int) event.getY()))) { // your view is clicked , perform you action
emergenyCallFAB.performClick();
isOutSideClicked = false;
} else { // clicked outside the button
isOutSideClicked = true;
}
}
}
return super.dispatchTouchEvent(event);
}
Upvotes: 1
Views: 482
Reputation: 3411
I have made changes to your code to make fab focus, and added comments where I made a change , let me know if anything still unclear.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.navigation.NavigationView
android:id="@+id/drawerNavigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/navigation_drawer_header"
app:insetForeground="@android:color/transparent"
app:menu="@menu/navigation_drawer_menu">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingLeft="20dp"
android:paddingTop="40dp"
android:paddingBottom="20dp">
<ImageView
android:id="@+id/logoutNavigationDrawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/logoutTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/logoutNavigationDrawer"
android:layout_toRightOf="@+id/logoutNavigationDrawer"
android:paddingLeft="14dp"
android:text="Log out"
android:textColor="@color/colorPrimaryDark"
android:textSize="16sp" />
</RelativeLayout>
</com.google.android.material.navigation.NavigationView>
<!-- added relative layout as you didn't have any view group using UI to distort in different devices-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- removed extra params , set visiblity gone to hide first time -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/emergencyCallFAB"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:layout_marginEnd="20dp"
android:visibility="gone"
android:layout_marginBottom="20dp"
android:src="@android:drawable/sym_call_incoming"/>
</RelativeLayout>
</androidx.drawerlayout.widget.DrawerLayout>
MainActivity
drawerLayout = findViewById(R.id.drawer_layout);
drawerLayout.setScrimColor(Color.parseColor("#00000000")); // set screen color behind navigation , this is what makes screen behind navigation looks as same color
navigationView = findViewById(R.id.drawerNavigationView);
emergenyCall = findViewById(R.id.emergencyCallFAB);
//NavigationDrawer Function
navigationView.bringToFront();
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
R.string.navigation_drawer_open, R.string.navigation_drawer_close){
public void onDrawerOpened(View drawerView){
super.onDrawerClosed(drawerView);
emergenyCall.setVisibility(View.VISIBLE); // make it visible and bring to front
emergenyCall.bringToFront();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
emergenyCall.setVisibility(View.VISIBLE);
emergenyCall.setAlpha(slideOffset); // makes it visible in animation , as drawer opens button becomes less faded and vice versa in case of close.
}
public void onDrawerClosed(View view){
super.onDrawerClosed(view);
emergenyCall.setVisibility(View.GONE); // hide button on drawer close
}
};
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
navigationView.setItemIconTintList(null);
Update : To make FAB clickable to need to override dispatchTouchEvent
and detect the touch on your button
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (drawerLayout.isDrawerOpen(navigationView)) {
View content = findViewById(R.id.emergencyCallFAB); // find the id of the view you want to check for clicable
int[] contentLocation = new int[2];
content.getLocationOnScreen(contentLocation);
Rect rect = new Rect(contentLocation[0],
contentLocation[1],
contentLocation[0] + content.getWidth(),
contentLocation[1] + content.getHeight());
if ((rect.contains((int) event.getX(), (int) event.getY()))) { // your view is clicked , perform you action
emergenyCall.performClick();
isOutSideClicked = false;
} else { // clicked outside the button
isOutSideClicked = true;
}
}
}
return super.dispatchTouchEvent(event);
}
Final Result
Upvotes: 1