I have created a main activity which has a fragment container in it, I am replacing many fragments in it on navigation menu option select. Its working fine, but the problem is:
When I click a navigation item twice, two identical fragments open, i have to press the back button twice to go back.
When all fragments are destroyed after pressing back, I see an empty page (which may be main activity page I guess).
layout_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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:id="#+id/main_activity_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/pageBackgroundColor"
tools:context="co.sd.app.MainActivity">
<RelativeLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/side_nav_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:padding="0sp"
app:menu="#menu/side_navigation_menu" />
</android.support.v4.widget.DrawerLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Bundle bundle;
private SessionManager session;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle actionBarToggle;
private TextView cartItemCountDisplay;
private NavigationView sideNavView;
private Menu sideNavViewMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout) findViewById(R.id.main_activity_page);
actionBarToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.OPEN, R.string.CLOSE);
drawerLayout.addDrawerListener(actionBarToggle);
actionBarToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
bundle = new Bundle();
sideNavView = ((NavigationView) findViewById(R.id.side_nav_drawer));
sideNavViewMenu = sideNavView.getMenu();
//To Display Home Fragment On Page Load
displaySelectedItemResult(sideNavViewMenu.findItem(R.id.nav_home));
//To Adjust Login or Logout option in side navigation menu
if (session.isUserLoggedIn()) {
sideNavViewMenu.findItem(R.id.nav_login).setVisible(false);
sideNavViewMenu.findItem(R.id.nav_logout).setVisible(true);
} else {
sideNavViewMenu.findItem(R.id.nav_login).setVisible(true);
sideNavViewMenu.findItem(R.id.nav_logout).setVisible(false);
}
//Operation on side navigation item click
sideNavView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
displaySelectedItemResult(item);
//navDrawerLayout.closeDrawers();
return true;
}
});
}
private void displaySelectedItemResult(MenuItem item) {
sideNavViewMenu.findItem(R.id.nav_home).setChecked(false);
sideNavViewMenu.findItem(R.id.nav_contactUs).setChecked(false);
sideNavViewMenu.findItem(R.id.nav_aboutUs).setChecked(false);
sideNavViewMenu.findItem(R.id.nav_login).setChecked(false);
sideNavViewMenu.findItem(R.id.nav_logout).setChecked(false);
Fragment fragment;
switch (item.getItemId()) {
case R.id.nav_user:
if (session.isUserLoggedIn()) {
item.setTitle(session.getUserDetails().get(SessionManager.KEY_NAME));
} else {
item.setTitle("Login First!");
}
drawerLayout.closeDrawer(GravityCompat.START);
break;
case R.id.nav_home:
fragment = new HomeFragment();
if (fragment != null) {
callNavMenuItemsFragment(fragment, "FRAG_HOME");
}
item.setChecked(true);
drawerLayout.closeDrawer(GravityCompat.START);
break;
case R.id.nav_contactUs:
fragment = new ContactUsFragment();
if (fragment != null) {
callNavMenuItemsFragment(fragment, "FRAG_CONTACT_US");
}
item.setChecked(true);
drawerLayout.closeDrawer(GravityCompat.START);
break;
case R.id.nav_aboutUs:
fragment = new AboutUsFragment();
if (fragment != null) {
callNavMenuItemsFragment(fragment, "FRAG_ABOUT_US");
}
item.setChecked(true);
drawerLayout.closeDrawer(GravityCompat.START);
break;
case R.id.nav_login:
new UserAuthentication(MainActivity.this, session).loginAndSignupDialog();
sideNavViewMenu.findItem(R.id.nav_login).setVisible(false);
sideNavViewMenu.findItem(R.id.nav_logout).setVisible(true);
item.setChecked(true);
drawerLayout.closeDrawer(GravityCompat.START);
break;
case R.id.nav_logout:
session.logoutUser();
sideNavViewMenu.findItem(R.id.nav_login).setVisible(true);
sideNavViewMenu.findItem(R.id.nav_logout).setVisible(false);
item.setChecked(true);
drawerLayout.closeDrawer(GravityCompat.START);
break;
default:
}
}
private FragmentTransaction callNavMenuItemsFragment(final Fragment fragment, final String fragmentTag) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.addToBackStack(null);
//if (!ACTIVE_FRAGMENT_ID.equals(String.valueOf(fragment.getId()))) {
if (!activeFragmentIDsList.contains(String.valueOf(fragment.getId()))) {
ft.replace(R.id.fragment_container, fragment, fragmentTag);
activeFragmentIDsList.add(String.valueOf(fragment.getId()));
}
ft.commit();
return ft;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (actionBarToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
case R.id.cart:
if (session.isUserLoggedIn()) {
startActivity(new Intent(MainActivity.this, CartActivity.class));
} else if (new UserAuthentication(MainActivity.this, session).loginAndSignupDialog()) {
startActivity(new Intent(MainActivity.this, CartActivity.class));
}
break;
default:
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actionbar_menu, menu);
final MenuItem menuItem = menu.findItem(R.id.cart);
MenuItemCompat.setActionView(menuItem, R.layout.cart_badge_layout);
final View actionView = MenuItemCompat.getActionView(menuItem);
cartItemCountDisplay = actionView.findViewById(R.id.cart_badge);
setupBadge();
actionView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setupBadge();
onOptionsItemSelected(menuItem);
}
});
return super.onCreateOptionsMenu(menu);
}
private void setupBadge() {
int itemCount = (((AppGlobalContent) getApplicationContext()).getSelectedItemsCount());
if (cartItemCountDisplay != null) {
if (itemCount == 0) {
if (cartItemCountDisplay.getVisibility() != View.GONE) {
cartItemCountDisplay.setVisibility(View.GONE);
}
} else {
cartItemCountDisplay.setText(String.valueOf(Math.min(itemCount, 99)));
if (cartItemCountDisplay.getVisibility() != View.VISIBLE) {
cartItemCountDisplay.setVisibility(View.VISIBLE);
}
}
}
}
#Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
Please suggest me on this.
This will fix your second problem, when you add fragments to your container they will be add to the stack,
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
finish();
}
else {
super.onBackPressed();
}
so when the stack entry count is 1 you have to finish the activity.
For the first problem you have to use "pop back stack" while adding the same fragment again use : getSupportFragmentManager().popBackStack();
Related
I am receiving the following crash reports from fabric.io (mainly after I added a SettingsActivity which can be loaded from my SlidingMenue to my App):
The code of to post the pendingRunnable has not been changed recently, anyway it started to receive the exceptions.
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1842)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1860)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:650)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:609)
at my.app.ui.activity.MainActivity$2.run(MainActivity.java:271)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5530)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:733)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:623)
This is my MainActivity.java
public class MainActivity extends AppCompatActivity implements MyAppFragment.OnListFragmentInteractionListener, AsyncResponse {
private MyAppDatabaseHandler myAppDatabaseHandler;
private SharedPreferences sharedpreferences;
private SharedPreferences defaultPrefs;
private FragmentA fragmentA;
public static boolean activityVisible = true;
private boolean isAttached;
private NavigationView navigationView;
private DrawerLayout drawer;
private View navHeader;
private Toolbar toolbar;
// index to identify current nav menu item
private static int navItemIndex = 0;
public static String CURRENT_TAG = MyAppConstants.TAG_A;
// toolbar titles respected to selected nav menu item
private String[] activityTitles;
// flag to load home fragment when user presses back key
private boolean shouldLoadHomeFragOnBackPress = true;
private Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.myAppDatabaseHandler= MyAppDatabaseHandler.getInstance(this);
defaultPrefs = PreferenceManager.getDefaultSharedPreferences(this);
sharedpreferences = getSharedPreferences(MyAppConstants.PREFERENCES, Context.MODE_PRIVATE);
setContentView(R.layout.activity_main);
fragmentA = new FragmentA();
// Init UI
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mHandler = new Handler();
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
// load toolbar titles from string resources
activityTitles = getResources().getStringArray(R.array.sliding_menu_item_activity_titles);
// load nav menu header data
loadNavHeader();
// initializing navigation menu
setUpNavigationView();
if (savedInstanceState == null) {
navItemIndex = 0;
CURRENT_TAG = MyAppConstants.TAG_A;
loadNextFragment();
}
}
/***
* Load navigation menu header information
* like background image, profile image
* name, website, notifications action view (dot)
*/
private void loadNavHeader() {
// Init NavigationHeader
}
/***
* Returns respected fragment that user
* selected from navigation menu
*/
private void loadNextFragment() {
// if user select the current navigation menu again, don't do anything
// just close the navigation drawer
if (getSupportFragmentManager().findFragmentByTag( CURRENT_TAG) != null && navItemIndex != 4) {
drawer.closeDrawers();
return;
}
if (navItemIndex == 4) {
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
} else {
// set toolbar title
setToolbarTitle();
// Sometimes, when fragment has huge data, screen seems hanging
// when switching between navigation menus
// So using runnable, the fragment is loaded with cross fade effect
// This effect can be seen in GMail app
Runnable mPendingRunnable = new Runnable() {
#Override
public void run() {
// update the activity_main_header_with_item content by replacing fragments
Fragment fragment = getNextFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commit();
}
};
// If mPendingRunnable is not null, then add to the message queue
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
}
}
//Closing drawer on item click
drawer.closeDrawers();
// refresh toolbar menu
invalidateOptionsMenu();
}
private Fragment getNextFragment() {
switch (navItemIndex) {
case 0:
// home
return this.fragmentA;
case 1:
FragmentB fragmentB = new FragmentB();
return fragmentB;
case 2:
// About Fragment
AboutFragment aboutFragment = new AboutFragment();
return aboutFragment;
case 3:
// Licence Fragment
LicenceFragment licenceFragment = new LicenceFragment();
return licenceFragment;
default:
return this.fragmentA;
}
}
private void setToolbarTitle() {
getSupportActionBar().setTitle(activityTitles[navItemIndex]);
}
private void setUpNavigationView() {
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()) {
//Replacing the activity_main_header_with_item content with ContentFragment Which is our Inbox View;
case R.id.nav_home:
navItemIndex = 0;
CURRENT_TAG = MyAppConstants.TAG_A;
break;
case R.id.nav_recently:
navItemIndex = 1;
CURRENT_TAG = MyAppConstants.TAG_B;
break;
case R.id.nav_about_us:
navItemIndex = 2;
CURRENT_TAG = MyAppConstants.TAG_ABOUT;
break;
case R.id.nav_licences:
navItemIndex = 3;
CURRENT_TAG = MyAppConstants.TAG_LICENCES;
break;
case R.id.nav_settings:
navItemIndex = 4;
// do not set CURRENT_TAG
break;
default:
navItemIndex = 0;
}
loadNextFragment();
return true;
}
});
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.openDrawer, R.string.closeDrawer) {
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawer.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessary or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawers();
return;
}
// This code loads home fragment when back key is pressed
// when user is in other fragment than home
if (shouldLoadHomeFragOnBackPress && CURRENT_TAG != MyAppConstants.TAG_A) {
// checking if user is on other navigation menu
// rather than home
if (navItemIndex != 0) {
navItemIndex = 0;
CURRENT_TAG = MyAppConstants.TAG_A;
loadNextFragment();
return;
}
}
finish();
super.onBackPressed();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main_header_with_item, menu);
// Disable Player Icon in case no player is found on device
Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, MyAppConstants.MUSIC_APP);
List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0);
if(activities == null || activities.size() <= 0) {
MenuItem player = menu.findItem(R.id.player);
if(player != null){
player.setVisible(false);
}
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
public void notifyOnDelete(View v) {
myAppDatabaseHandler.deleteAll();
}
#Override
public void onListFragmentInteraction(Song item) {
}
#Override
public void processFinish(String output) {
if (isAttached) {
...
}
}
#Override
public void onAttachedToWindow() {
isAttached = true;
super.onAttachedToWindow();
}
#Override
public void onDetachedFromWindow() {
isAttached = false;
super.onDetachedFromWindow();
}
#Override
public void onResume() {
activityVisible = true;
updateFragmentA();
super.onResume();
}
#Override
public void onPause() {
activityVisible = false;
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onStart() {
super.onStart();
}
public void updateFragmentA() {
if (CURRENT_TAG == MyAppConstants.TAG_A) {
Timber.i( "updating FragmentA");
fragmentA.swap();
}
}
}
Any ideas about the cause of this issue?
Try this first setContentView(R.layout.activity_main); than perform your action
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.myAppDatabaseHandler= MyAppDatabaseHandler.getInstance(this);
defaultPrefs = PreferenceManager.getDefaultSharedPreferences(this);
sharedpreferences = getSharedPreferences(MyAppConstants.PREFERENCES, Context.MODE_PRIVATE);
I'm building an app which contains a NavigationDrawer to navigate between Fragments.
For some reason, when pressing on any item in the Navigation Drawer the item just marks itself and doesn't change the fragment (tried debug but the item clicks doesn't calls the functions)
The fragment is not loading in first click..i have to press twice to reload the fragment
Main Activity:
public class MainActivity extends AppCompatActivity {
private NavigationView navigationView;
private DrawerLayout drawer;
private View navHeader;
private ImageView imgNavHeaderBg, imgProfile;
private TextView txtName, txtCity;
private Toolbar toolbar;
private FloatingActionButton fab;
// urls to load user profile & background
private static final String urlNavHeaderBg = "";
private static final String urlProfileImg = "";
//current menu pressed
public static int navItemIndex = 0;
//tags for fragments
private static final String TAG_HOME = "home";
private static final String TAG_PROFILE = "profile";
private static final String TAG_RATEUS = "rate us";
private static final String TAG_SCORE = "rate score";
private static final String TAG_NOTIFICATIONS = "notifications";
private static final String TAG_SETTINGS = "settings";
public static String CURRENT_TAG = TAG_HOME;
private String[] activityTitles;
private boolean shouldLoadHomeFragOnBackPress = true;
private Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mHandler = new Handler();
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
fab = (FloatingActionButton) findViewById(R.id.fab);
//nav view header
navHeader = navigationView.getHeaderView(0);
txtName = (TextView) navHeader.findViewById(R.id.name);
txtCity = (TextView) navHeader.findViewById(R.id.city);
imgNavHeaderBg = (ImageView) navHeader.findViewById(R.id.img_header_bg);
imgProfile = (ImageView) navHeader.findViewById(R.id.img_profile);
//load the toolbar titles
activityTitles = getResources().getStringArray(R.array.nav_item_activity_titles);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Make action here", Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
});
//load the navigator header data
loadNavHeader();
//initialize nav menu
setUpNavigationView();
if (savedInstanceState == null) {
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
loadHomeFragment();
}
}
private void loadNavHeader() {
txtName.setText("My Name");
txtCity.setText("Somewhere, Europe");
Glide.with(this).load(urlNavHeaderBg).crossFade().diskCacheStrategy(DiskCacheStrategy.ALL).into(imgNavHeaderBg);
Glide.with(this).load(urlProfileImg).thumbnail(0.5f).bitmapTransform(new CircleTransform(this)).diskCacheStrategy(DiskCacheStrategy.ALL).into(imgProfile);
navigationView.getMenu().getItem(4).setActionView(R.layout.menu_dot);
}
private void loadHomeFragment() {
selectNavMenu();
setToolBarTitle();
if (getSupportFragmentManager().findFragmentByTag(CURRENT_TAG) != null) {
drawer.closeDrawers();
toggleFab();
return;
}
Runnable mPendingRunnable = new Runnable() {
#Override
public void run() {
Fragment fragment = getHomeFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commitAllowingStateLoss();
}
};
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
}
toggleFab();
drawer.closeDrawers();
invalidateOptionsMenu();
}
private Fragment getHomeFragment() {
switch (navItemIndex) {
case 0:
HomeFragment homeFragment = new HomeFragment();
return homeFragment;
case 1:
ProfileFragment profileFragment = new ProfileFragment();
return profileFragment;
case 2:
RateusFragment rateusFragment = new RateusFragment();
return rateusFragment;
case 3:
ScoreFragment scoreFragment = new ScoreFragment();
return scoreFragment;
case 4:
NotificationsFragment notificationsFragment = new NotificationsFragment();
return notificationsFragment;
case 5:
SettingsFragment settingsFragment = new SettingsFragment();
return settingsFragment;
default:
return new HomeFragment();
}
}
private void setToolBarTitle() {
getSupportActionBar().setTitle(activityTitles[navItemIndex]);
}
private void selectNavMenu() {
navigationView.getMenu().getItem(navItemIndex).setCheckable(true);
}
private void setUpNavigationView() {
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.nav_home:
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
break;
case R.id.nav_profile:
navItemIndex = 1;
CURRENT_TAG = TAG_PROFILE;
break;
case R.id.nav_rateus:
navItemIndex = 2;
CURRENT_TAG = TAG_RATEUS;
break;
case R.id.nav_score:
navItemIndex = 3;
CURRENT_TAG = TAG_SCORE;
break;
case R.id.nav_notifications:
navItemIndex = 4;
CURRENT_TAG = TAG_NOTIFICATIONS;
break;
case R.id.nav_settings:
navItemIndex = 5;
CURRENT_TAG = TAG_SETTINGS;
break;
case R.id.nav_about_us:
startActivity(new Intent(MainActivity.this, AboutUsActivity.class));
drawer.closeDrawers();
return true;
case R.id.nav_terms:
startActivity(new Intent(MainActivity.this, TermsActivity.class));
drawer.closeDrawers();
return true;
default:
navItemIndex = 0;
}
if (menuItem.isChecked()) {
menuItem.setChecked(false);
} else {
menuItem.setChecked(true);
}
menuItem.setChecked(true);
return true;
}
});
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.openDrawer, R.string.closeDrawer) {
#Override
public void onDrawerClosed(View drawerView) {
//when nav closed this will triggered - leaving blank so nothing won't happen
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
//when nav opened this will triggered - leaving blank so nothing won't happen
super.onDrawerOpened(drawerView);
}
};
drawer.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawers();
return;
}
if (shouldLoadHomeFragOnBackPress) {
if (navItemIndex != 0) {
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
loadHomeFragment();
return;
}
}
super.onBackPressed();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (navItemIndex == 0) {
getMenuInflater().inflate(R.menu.main, menu);
}
if (navItemIndex == 4) {
getMenuInflater().inflate(R.menu.notifications, menu);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_logout) {
Toast.makeText(getApplicationContext(), "Logout user!", Toast.LENGTH_LONG).show();
return true;
}
if (id == R.id.action_mark_all_read) {
Toast.makeText(getApplicationContext(), "All marked as read!", Toast.LENGTH_LONG).show();
}
if (id == R.id.action_clear_notifications) {
Toast.makeText(getApplicationContext(), "All Cleared!", Toast.LENGTH_LONG).show();
}
return super.onOptionsItemSelected(item);
}
private void toggleFab() {
if (navItemIndex == 0)
fab.show();
else
fab.hide();
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
tools:context=".activity.MainActivity">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
There are couple of problems with the code:
Make sure u add break in switch:
case R.id.nav_about_us:
startActivity(new Intent(MainActivity.this, AboutUsActivity.class));
drawer.closeDrawers();
break; //add break
case R.id.nav_terms:
startActivity(new Intent(MainActivity.this, TermsActivity.class));
drawer.closeDrawers();
break;
default:
navItemIndex = 0;
break;
Also your fragment not loading as you are not calling the function properly:
in your Switch case:
case R.id.nav_home:
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
Fragment fragment = getHomeFragment(); //get fragment based on index
ReplaceFragment(fragment); //now replace them and load new one
drawer.closeDrawers();
break;
in ReplaceFragment method write:
public void ReplaceFragment(Fragment r_fragment) {
if (r_fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame, r_fragment).commit();
} else {
// error in creating fragment
}
}
Also overWrite following methods:
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
drawerView.bringToFront(); //add this two lines
drawerView.requestLayout();
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
actionBarDrawerToggle.syncState();
}
I have the following Activity code:-
public class legislator_info extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_legislator_info);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Legislator Info");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent i = getIntent();
String bioguide = i.getExtras().getString("Person");
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// click on 'up' button in the action bar, handle it here
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
So basically I have a fragment which has a list view displayed in it. On click of a list Item I start this activity and I want to go back to the previous fragment on the back button click. I tried the above code but I am not able to travel back. Am pretty new at this any help is appreciated.
I have added my fragment in the following way:-
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
LegislatorFragment lf = new LegislatorFragment();
ft.replace(R.id.fragment_container,lf);
ft.addToBackStack(null);
ft.commit();
I am still not clear what you want to achieve but you can try this
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
EDIT:
case android.R.id.home:
//call onBackPressed here
onBackPressed();
return true;
You have to override onOptionsItemSelected because you are trying with Action bar's back button.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
Then override BackPressed -
#Override
public void onBackPressed()
{
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
}
else {
super.onBackPressed();
}
}
I use MaterialDrawer and code MainActivity is:
public class MainActivity extends AppCompatActivity implements KitchenFragment.CallbackOne {
public static final String TAG = "myLogTag";
private Toolbar mToolbar;
private Drawer drawer;
private FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "CLICK NOCL");
}
});
setSupportActionBar(mToolbar);
// getSupportActionBar().setDisplayHomeAsUpEnabled(false);
fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.content_frame);
if (fragment == null) {
fragment = MenuFragment.newInstance();
fm.beginTransaction()
.add(R.id.content_frame, fragment)
.commit();
}
drawer = new DrawerBuilder()
.withActivity(this)
.withToolbar(mToolbar)
.withActionBarDrawerToggle(true)
.withHeader(R.layout.drawer_header)
.addDrawerItems(
new PrimaryDrawerItem().withName(R.string.menu).withIdentifier(1),
new PrimaryDrawerItem().withName(R.string.kitchen_title).withIdentifier(2),
new PrimaryDrawerItem().withName(R.string.information_title).withEnabled(false)
).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
Log.d(TAG, "position clicked: " + position);
Fragment fragment = MenuFragment.newInstance();
switch (position) {
case 1:
fragment = MenuFragment.newInstance();
break;
case 2:
fragment = KitchenFragment.newInstance();
break;
default:
fragment = new Fragment();
}
fm.beginTransaction().replace(R.id.content_frame, fragment).commit();
return false;
}
})
.withFireOnInitialOnClick(true)
.withSavedInstance(savedInstanceState)
.withOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() {
#Override
public boolean onNavigationClickListener(View view) {
Log.d(TAG, "CLICK in DNL");
if (!drawer.getActionBarDrawerToggle().isDrawerIndicatorEnabled()) {
onBackPressed();
return true;
} else
return false;
}
})
.build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "CLICK OIS");
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case android.R.id.home:
getFragmentManager().popBackStackImmediate();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState = drawer.saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen())
drawer.closeDrawer();
else if (getFragmentManager().getBackStackEntryCount() == 1) {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawer.getActionBarDrawerToggle().syncState();
getFragmentManager().popBackStack();
} else if (getFragmentManager().getBackStackEntryCount() > 0)
getFragmentManager().popBackStack();
else
super.onBackPressed();
}
#Override
public void setFirstSelected() {
drawer.setSelection(1);
}
}
I'm trying to trace a Click in mToolbar.setNavigationOnClickListener
and withOnDrawerNavigationListener and onOptionsItemSelected.
None of the listeners not reacted for clicking.
How you see i use Activity that launches Fragment (1), which in turn lets Fragment (2 and 3). In 2 and 3 Fragment in OnCreate i use ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); , and I need to by pressing the back button (in toolbar), returning the previous fragment, and not open Drawer
The MaterialDrawer already handles all the listeners for you. If you need to do an action after the drawer opens or closes you can provide the listener via the DrawerBuilder
For the icon you have this listener:
OnDrawerNavigationListener
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1158
For drawer close / open this listener:
OnDrawerListener
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1116
I suggest you to create new Activity using android studio wizard. File->New->Activity->Navigation Drawer Activity.
In that case ActionBarDrawerToaggle is used
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
This toggle contains click listener which handle open/close drawer functionality for you.
Also you can that item clicks implemented through OnNavigationItemSelectedListener.onNavigationItemSelected(MenuItem item)
in my navigation drawer there are 5 menu items.one of them is about us item.when I click on this item, I call AboutUsFragment and show it(its content is just a text).but when I click onBackPress, fragment is gone but its texts remains on my activity.how can I solve this problem?what`s it related to?!
select item of navigation drawer in my activity:
public void selectItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
if (!Constants.login_state) {
fragment = new LoginFragment();
} else {
Logout();
}
break;
case 1:
Constants.filter = false;
Constants.gender = "-1";
fragment = new HomeFragment();
break;
case 2:
Constants.filter = false;
Constants.gender = "2";
StyleFragment.SortingMode = 1;
fragment = new StyleFragment();
break;
case 3:
Constants.filter = false;
Constants.gender = "1";
StyleFragment.SortingMode = 1;
fragment = new StyleFragment();
break;
case 4:
fragment = new AboutUsFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentTransaction fragmentManager = getSupportFragmentManager().beginTransaction();
fragmentManager.replace(R.id.rl_container, fragment);
fragmentManager.addToBackStack(null);
fragmentManager.commit();
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(Gravity.END);
} else {
Log.e("HomeActivity", "Error in creating fragment");
}
}
and AboutUsFragment:
public class AboutUsFragment extends android.support.v4.app.Fragment{
private View view;
private TextView about_us_fragment_text_view;
public static AboutUsFragment newInstance() {
AboutUsFragment fragment = new AboutUsFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view=inflater.inflate(R.layout.fragment_about_us, container, false);
Casting(view);
about_us_fragment_text_view.setText(getResources().getString(R.string.about_us));
ChangeUIFont.ChangeFont((ViewGroup) view, getContext());
return view;
}
//casting parameters
public void Casting(View v){
about_us_fragment_text_view= (TextView) v.findViewById(R.id.about_us_fragment_text_view);
}}
onBackPress in my activity:
#Override
public void onBackPressed() {
if (SearchOpened) {
lv_searchResult.setVisibility(View.GONE);
SearchOpened = false;
} else
super.onBackPressed();
}
---------------------------------------AfterSearching-------------------------------------------
Finally I found the solution!
in my fragment I added below code:
public static final String FRAGMENT_NAME = AboutUsFragment.class.getName();
and in my activity,I set the tag of fragment when I call it,instead of null!
fragmentManager.replace(R.id.rl_container, fragment,fragmentName);
used this method instead of onBackPressed
if you have toolbar then here is my solution,
type under the oncreate method below toolbar,
assert getSupportActionBar() != null;
// getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
and set this code in your manifest file for your fragment
<activity android:name=".yourCurrentFragment">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".whichActivityYouWantToGo" />
</activity>
Try this:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}