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">
Related
This question already has an answer here:
Navigation View Global Action Back State
(1 answer)
Closed 1 year ago.
I have a search button, with an actionViewClass. When this button is clicked a new fragment opens, and I want when the back button is clicked to go back to the previous fragment.
PS: I am using navigation graph
My toolbar_menu.xml
<item
android:id="#+id/search"
android:title="Pesquisar"
android:orderInCategory="103"
android:icon="#drawable/ic_search"
android:iconTint="#color/colorPrimary"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
MainActivity.java
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.search:
getSupportFragmentManager().beginTransaction()
.replace(R.id.navHostFragment, new ContaFragment())
.commit();
break;
}
return false;
}
});
try adding the fragment to backstack
private void replaceFragment (Fragment fragment){
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.navHostFragment, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
}
this question has a good answer and explanation here How to resume Fragment from BackStack if exists
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'm making an app that has launches with a Swiping Tabs Fragment, but I also want to have a Preferences menu using Fragment Transaction. When I press the Settings button in my app, the preferences menu does appear and is interactive, but the layout seems to be transparent showing the Tabs below. Is there anything that can be done to fix this, or is there a better method?
Code that calls the Preferences Menu from the Options:
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getFragmentManager().popBackStackImmediate();
break;
case R.id.logout:
FirebaseAuth.getInstance().signOut();
finish();
startActivity(new Intent(this, Activity_Main.class));
break;
case R.id.action_settings:
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new Fragment_Settings()).addToBackStack(null)
.commit();
break;
}
return true;
}
Code that calls Tabs Fragments:
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new Fragment_Flower();
case 1:
// Games fragment activity
return new Fragment_Overview();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Initialising Transaction in onCreate:
startService(new Intent(this, SensorListener.class));
if (b == null) {
// Create new fragment and transaction
Fragment newFragment = new Fragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
//Replace whatever is in the fragment_container view with this
// fragment,
// and add the transaction to the back stack
transaction.replace(android.R.id.content, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
Any help will be greatly appreciated!
Just set background color in your layout file. It may avoid transparent backgound.
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
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");