I would like to implement the sign out method in my project. i watch all youtube tutorial but seems like the navigation drawer is the update version. and i'm clueless on how to implement those sign out coding into my coding.
the newest version of the navigation drawer already built in with the ui package folder. So i'm not quite sure on how to implement those tutorial code because most of the tutorial code have this code. below is the tutorial code and i don't know on how to implement the sign out method into my home.java code. thank you
@SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. int id = item.getItemId(); if (id == R.id.nav_home) { getSupportActionBar().setTitle("Home"); getSupportFragmentManager().beginTransaction().replace(R.id.container,new HomeFragment()).commit(); } else if (id == R.id.nav_profile) { getSupportActionBar().setTitle("Profile"); getSupportFragmentManager().beginTransaction().replace(R.id.container,new ProfileFragment()).commit(); } else if (id == R.id.nav_settings) { getSupportActionBar().setTitle("Settings"); getSupportFragmentManager().beginTransaction().replace(R.id.container,new SettingsFragment()).commit(); } else if (id == R.id.nav_signout) { FirebaseAuth.getInstance().signOut(); Intent loginActivity = new Intent(getApplicationContext(),LoginActivity.class); startActivity(loginActivity); finish(); } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } this is my home.java code
package com.example.guru; import android.os.Bundle; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import android.view.View; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.NavigationUI; import com.google.android.material.navigation.NavigationView; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import androidx.drawerlayout.widget.DrawerLayout; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.view.Menu; import android.widget.TextView; public class Home extends AppCompatActivity { FirebaseAuth firebaseAuth; FirebaseUser currentUser; DatabaseReference databaseReference; private AppBarConfiguration mAppBarConfiguration; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); //ini firebaseAuth = FirebaseAuth.getInstance(); currentUser = firebaseAuth.getCurrentUser(); databaseReference = FirebaseDatabase.getInstance().getReference("Customer"); FloatingActionButton fab = findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); DrawerLayout drawer = findViewById(R.id.drawer_layout); NavigationView navigationView = findViewById(R.id.nav_view); // Passing each menu ID as a set of Ids because each // menu should be considered as top level destinations. mAppBarConfiguration = new AppBarConfiguration.Builder( R.id.nav_home, R.id.nav_profile, R.id.nav_orders,R.id.nav_logout) .setDrawerLayout(drawer) .build(); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupWithNavController(navigationView, navController); updateNavHeader(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.home, menu); return true; } @Override public boolean onSupportNavigateUp() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); return NavigationUI.navigateUp(navController, mAppBarConfiguration) || super.onSupportNavigateUp(); } public void updateNavHeader() { NavigationView navigationView = findViewById(R.id.nav_view); View headerView= navigationView.getHeaderView(0); TextView navName= headerView.findViewById(R.id.txtName); TextView navEmail=headerView.findViewById(R.id.txtEmail); navName.setText(currentUser.getDisplayName()); navEmail.setText(currentUser.getEmail()); } } LogoutFragment
import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.Nullable; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; import com.example.guru.R; public class LogoutFragment extends Fragment { private LogoutViewModel logoutViewModel; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { logoutViewModel = ViewModelProviders.of(this).get(LogoutViewModel.class); View root = inflater.inflate(R.layout.fragment_logout, container, false); final TextView textView = root.findViewById(R.id.text_logout); logoutViewModel.getText().observe(this, new Observer<String>() { @Override public void onChanged(@Nullable String s) { textView.setText(s); } }); return root; } } and this is my LogoutViewModel
package com.example.guru.ui.Logout; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; public class LogoutViewModel extends ViewModel { private MutableLiveData<String> mText; public LogoutViewModel() { mText = new MutableLiveData<>(); mText.setValue("logout"); } public LiveData<String> getText() { return mText; } } 23 Answers
Feels like there should be a built in solution but so far I have solved it like this. I simply add a click listener on that menu option, in my case my logout button:
In Java -->
NavigationView navigationView = findViewById(R.id.nav_view); navigationView.getMenu().findItem(R.id.logout).setOnMenuItemClickListener(menuItem -> { logout(); return true; }); In Kotlin -->
navView.getMenu().findItem(R.id.nav_logout).setOnMenuItemClickListener({ menuItem -> logoutDialog() true }) 1my navigation menu code
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="" xmlns:tools="" tools:showIn="navigation_view"> <item android:id="@+id/nav_share" android:icon="@drawable/ic_menu_share" android:title="@string/menu_share" /> <item android:id="@+id/logout" android:icon="@drawable/logout" android:title="Logout" /> <item android:id="@+id/login" android:icon="@drawable/logout" android:title="Login" /> </menu> code inside onResume method , this will hide either sign out or sign in button depending upon auth state of user
@Override protected void onResume() { super.onResume(); if (auth.getCurrentUser() == null) { navigationView.getMenu().findItem(R.id.logout).setVisible(false); navigationView.getMenu().findItem(R.id.login).setVisible(true); // perform action when user is not logged in } else { navigationView.getMenu().findItem(R.id.logout).setVisible(true); navigationView.getMenu().findItem(R.id.login).setVisible(false); // perform action when user is already logged in } } Handle navigation view item clicks here.
@SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.logout) { auth.signOut(); onResume(); } else if (id == R.id.login) { //handle event login button pressed startActivity(new Intent(MainActivity.this, LoginActivity.class)); } DrawerLayout drawer = findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } Hope this will help you
2I found two solution to handle it.
1. If you have register your fragment in navigation graph than
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() { @Override public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) { if (destination.getId() == R.id.logout){ logout(); } } }); 2. If you don't have register fragment in navigation graph and you just want to handle click event on drawer menu.
mNavigationView.getMenu().findItem(R.id.nav_logout).setOnMenuItemClickListener(menuItem -> { AppUtils.showLongToast("this works", getApplicationContext()); return true; });