I'll try and explain this the best I can and I'm sure there will be a simple explanation to this.
I have a navigation menu with a logout option. The menu items are all in a switch case except for the logout which I have separated and used an IF statement. I got it to logout and go straight back to the login screen but I didn't think that was great for UX so I tried to add an alertdialog box to give the user the option to confirm whether or not they definitely want to logout or not.
I tried this (this is just the switch):
navigationView = findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.nav_home:
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new HomeFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle("");
item.setCheckable(true);
mDrawerLayout.closeDrawers();
break;
case R.id.nav_create_case:
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new CreateCaseFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle("Create a Case");
item.setCheckable(true);
mDrawerLayout.closeDrawers();
break;
case R.id.nav_barcode_scanner:
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new BarcodeScannerFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle("Barcode Scanner");
item.setCheckable(true);
mDrawerLayout.closeDrawers();
break;
case R.id.nav_checklists:
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new ChecklistsFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle("Checklists");
item.setCheckable(true);
mDrawerLayout.closeDrawers();
break;
case R.id.nav_create_report:
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new CreateReportFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle("Create Report");
item.setCheckable(true);
mDrawerLayout.closeDrawers();
break;
}
if (item.getItemId() == R.id.nav_logout) {
final AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("Logout");
alert.setMessage("Are you sure you wish to logout?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
FirebaseAuth.getInstance().signOut();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent i2 = new Intent(MainActivity.this, MainActivity.class);
i2.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i2);
}
});
So with this, the logout button does nothing. Doesn't crash or anything. Just does nowt.
Any help greatly appreciated. Especially if I've done something stupid.
Thanks in advance
You are missing a show statement:
alert.show();
It's similar to a toast, you have to explicitly call show() to show the dialog
Related
I have 3 and more fragments and I want to access them with the drawer.
So that when I click on "Profile" the current fragment(i.e. Home) should hide and "Profile" fragment should show and vice versa..
Right now its working with "replace fragment" but,
Instead of replace I want to show/hide them when I click on the drawer button.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//my coding
replace(new HomeFragment());
init();
}
private void init() {
mDrawer = (FlowingDrawer) findViewById(R.id.drawerlayout);
iv_Menu = findViewById(R.id.iv_Menu);
ll_Home = findViewById(R.id.ll_Home);
ll_Profile = findViewById(R.id.ll_Profile);
ll_Setting = findViewById(R.id.ll_Setting);
ll_Share = findViewById(R.id.ll_Share);
ll_Logout = findViewById(R.id.ll_Logout);
iv_Menu.setOnClickListener(this);
ll_Home.setOnClickListener(this);
ll_Profile.setOnClickListener(this);
ll_Setting.setOnClickListener(this);
ll_Share.setOnClickListener(this);
ll_Logout.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.iv_Menu:
mDrawer.openMenu(true);
break;
case R.id.ll_Home:
replace(new HomeFragment(),"Home");
mDrawer.closeMenu(true);
break;
case R.id.ll_Profile:
replace(new ProfileFragment(),"Profile");
mDrawer.closeMenu(true);
break;
case R.id.ll_Setting:
startActivity(new Intent(this, SimplPreach.class));
mDrawer.closeMenu(true);
break;
case R.id.ll_Share:
Toast.makeText(this, "Share.", Toast.LENGTH_SHORT).show();
mDrawer.closeMenu(true);
break;
case R.id.ll_Logout:
Toast.makeText(this, "Logout.", Toast.LENGTH_SHORT).show();
mDrawer.closeMenu(true);
break;
}
}
private void replace(Fragment fragment, String s) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_Main,fragment);
transaction.addToBackStack(s);
transaction.commit();
}
private void replace(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_Main,fragment);
transaction.commit();
}
I have been searching from hours but nothing is working,
How can I use show hide instead of replace ..
Please help me..
FragmentTransaction has the following methods you can use.
show(Fragment fragment)
hide(Fragment fragment)
add(int containerViewId, Fragment fragment, String tag)
And I think you don't need to call transaction.addToBackStack(s) in your case.
I am trying to switch to a new screen when the user clicks on one of the options. This code is nested in the main activity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about_settings:
Log.d("tcc", "This is getting to the about fragment");
startActivity(new Intent(MainActivity.this, HelpFragment.class));
return true;
case R.id.help_settings:
Log.d("tcc", "This is getting to the help fragment");
startActivity(new Intent(MainActivity.this, SettingsFragment.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I am then trying to get it to switch to one of the fragments that I have created. When I do this though I am getting an error:
Unable to instantiate activity ComponentInfo{info.hccis.bookingapplication/info.hccis.bookingapplication.SettingsFragment}: java.lang.ClassCastException: info.hccis.bookingapplication.SettingsFragment cannot be cast to android.app.Activity
You want to do Fragment Transactions not startActivity :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
FragmentManager fragmentManager = getSupportFragmentManager();
switch (item.getItemId()) {
case R.id.about_settings:
Log.d("tcc", "This is getting to the about fragment");
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, new HelpFragment());
fragmentTransaction.addToBackStack(null); // to provided navigation when back is clicked
fragmentTransaction.commit();
return true;
case R.id.help_settings:
Log.d("tcc", "This is getting to the help fragment");
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, new SettingsFragment());
fragmentTransaction.addToBackStack(null); // to provided navigation when back is clicked
fragmentTransaction.commit();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
And define a fragment coinainer/which will be replaced by your
fragments: in your Activity's View:
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
In my application I have NavigationView and into this NavigationView I have set menu for open some fragments!
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="320dip"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#000"
android:fitsSystemWindows="true"
app:headerLayout="#layout/tester_drawer_header"
app:itemIconTint="#fff"
app:itemTextColor="#fff"
app:menu="#menu/tester_drawer_main"/>
I want when click on this menu open one fragment and I want when go to nested fragments and press onBack button open first fragment not open backStack fragments!
I write below codes, but after click on back button back fragments from backStack, but I want just open first fragment!
MyActivity codes:
public class TesterDashboardActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tester_dashboard);
loadFragment(new TesterTestListFragment(), userName);
}
#Override
public void onBackPressed() {
fragmentBackCount = getSupportFragmentManager().getBackStackEntryCount();
if (fragmentBackCount <= 1) {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
//finishAffinity();
super.onBackPressed();
}
} else {
getSupportFragmentManager().popBackStack();
}
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.nav_home:
loadFragment(new TesterTestListFragment(), userName);
break;
case R.id.nav_billing:
loadFragment(new TesterFinanceFragment(), context.getString(R.string.menu_billing));
break;
case R.id.nav_edit_profile:
loadFragment(new TesterProfileFilterEditFragment(), context.getString(R.string.menu_edit_profile));
break;
case R.id.nav_bank:
loadFragment(new TesterShebaFragment(), context.getString(R.string.menu_bank));
break;
case R.id.nav_report:
loadFragment(new TesterReportsFragment(), context.getString(R.string.menu_report));
break;
case R.id.nav_setting:
loadFragment(new TesterSettingFragment(), context.getString(R.string.menu_setting));
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
public void loadFragment(Fragment fragment, String toolbarTitle) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.testerFragment, fragment,TAG_FRAGMENT);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
toolbar.setTitle(toolbarTitle);
}
How can I fix it?
In your code I found when the fragmentBackCount>1 you just call getSupportFragmentManager().popBackStack(); once, so you will see top fragment on backstack.
I think you should call getSupportFragmentManager().popBackStack();, fragmentBackCount-1 time to reach the first fragmnet
else {
for(int i=0;i<fragmentBackCount-1;i++)
getSupportFragmentManager().popBackStack();
}
When you are transitioning between Fragments, call addToBackStack() as part of your
FragmentTransaction:
FragmentTransaction tx = fragmentManager.beginTransation();
tx.replace( R.id.fragment, new MyFragment() ).addToBackStack( "tag" ).commit();
I have been looking for a way to open a secondary activity from a menu item click. After several different attempts to find an answer to my question in other people's posts, I decided to ask a question. Help would be much appreciated in the form of code snippets to apply quickly, thank you :)
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_gallery) {
MainFragment fragment = new MainFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
//open gallery
startActivity(new Intent(MainActivity.this, PhotoGallery.class));
}
else if (id == R.id.nav_share) {
MainFragment fragment = new MainFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,fragment);
fragmentTransaction.commit();
}
else if (id == R.id.nav_msg)
{
MainFragment fragment = new MainFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,fragment);
fragmentTransaction.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_gallery) {
//open gallery
Intent galleryIntent = new Intent(YourCurrentActivity.this, PhotoActivity.class);
//if you need to pass data:
Bundle mBundle = new Bundle();
mBundle.putString("myKey", "opengalleryclicked");
galleryIntent.putExtras(mBundle);
startActivity(galleryIntent);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Data passed can be received in your second activity by:
String value = getIntent().getExtras().getString("myKey");
When I press the "Back" button (tested both on emulator and Galaxy S2) the applciation closes, no matter how many fragment transactions have been commited :(
Ok, just in case, I'll post my implementation of fragment transactions although I doubt they are the problem
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
Fragment fragment;
switch(tab.getPosition()) {
case(0):
fragment = new Fragment1();
break;
case(1):
fragment = new Fragment2();
break;
case(2):
fragment = new Fragment3();
break;
default:
fragment = new Fragment();
Toast.makeText(getBaseContext(), "Error", Toast.LENGTH_SHORT).show();
break;
}
Bundle args = new Bundle();
fragment.setArguments(args);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.okvir, fragment);
ft.addToBackStack(null);
ft.commit();
}
And also
public void searchResultsView(List<School> results) {
setResults(results);
FragmentResults searchFragment = new FragmentResults();
Bundle args = new Bundle();
searchFragment.setArguments(args);
getFragmentManager().beginTransaction().replace(R.id.okvir, searchFragment).addToBackStack(null).commit();
}
And now I'll try to provide technical details about the application so you can figure out what's holding it back (irony).
The application has one Activity, and as you could conclude, utilizes ActionBar to initialize TabHost. The ActionBar.TabHost has three tabs attached to it which correspond to Fragment1, Fragment2, Fragment3. The FragmentResults is called from Fragment2 tab. If you require additional info, let me know in the comments.
Thank you for your time and effort. Cheers
P.S. Interenstingly, when I call DialogFragment, even without AddToBackStack(null) method pressing "Back" button returns to the fragment that called it and doesn't close the app...
CHANGE THIS:
ft.replace(R.id.okvir, fragment);
ft.addToBackStack(null);
ft.commit();
TO THIS:
ft.replace(R.id.okvir, fragment,"TAGNAME");
ft.addToBackStack("TAGNAME");
ft.commit();
I WAS OMRI FROM ISRAEL HOPE ITS HELP IF U HAVE MORE PROBLAM CONTECT ME
omlrc1991#gmail.com