ActionBarDrawerToggle disappears when addToBackStack(null) is used - android

In the selectItem() method, adding .addToBackStack(null) to my transaction seems to break the toggle button (the one that brings out the nav drawer when tapped). It just disappears entirely when a fragment is loaded (by clicking on the corresponding item in the nav drawer). If I comment out that line, the toggle button remains and works perfectly fine.
I need to call addToBackStack because I want back button functionality to work for those fragments, though. Why is it causing this issue?
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
Log.d(TAG, "Item " + position + " selected");
selectItem(position);
}
}
/** Swaps fragments in the main content view */
private void selectItem(int position) {
// Create a new fragment and specify the planet to show based on position
Fragment aboutFragment = new AboutFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
Log.d(TAG, "selectItem() with position " + position);
switch(position) {
case 0:
fragmentManager.beginTransaction()
.replace(R.id.contributionsFragmentContainer, contributionsList)
//.addToBackStack(null)
.commit();
Log.d(TAG, "contributionsListFragment committed");
break;
case 1:
fragmentManager.beginTransaction()
.replace(R.id.contributionsFragmentContainer, aboutFragment)
//.addToBackStack(null)
.commit();
Log.d(TAG, "aboutFragment committed");
break;
}
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(itemArray[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
if (title != null && getActionBar() != null) {
getActionBar().setTitle(title);
}
}
private void addDrawerItems() {
itemArray = new String[] {"Home", "About", "Nearby", "Settings", "Feedback"};
Log.d(TAG, "Adding to itemArray");
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, itemArray);
mDrawerList.setAdapter(mAdapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
}
private void setupDrawer() {
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(R.string.title_activity_contributions);
setContentView(R.layout.activity_contributions);
Log.d("ContributionsActivity", "onCreate()");
// Activity can call methods in the fragment by acquiring a reference to the Fragment from FragmentManager, using findFragmentById()
contributionsList = (ContributionsListFragment) getSupportFragmentManager().findFragmentById(R.id.contributionsListFragment);
//Set up navigation drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//getSupportActionBar().setHomeButtonEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.drawer_list);
addDrawerItems();
setupDrawer();
...
}

Related

Custom navigation drawer with activity & fragment

This is the code of the main activity, that contains a lateral menu with three button, what that i want to do is :
Modify this code and replace the action in the "listener" of the buttons in lateral menu, now when i press a button, a new fragment is created, but i want create a new activity (NOT a fragment), maintaining the layout (lateral menu).
How i can do this ?
public class MainActivity extends Activity {
// declare properties
private String[] mNavigationDrawerItemTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
// nav drawer title
private CharSequence mDrawerTitle;
// used to store app title
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// for proper titles
mTitle = mDrawerTitle = getTitle();
// initialize properties
mNavigationDrawerItemTitles = getResources().getStringArray(R.array.navigation_drawer_items_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// list the drawer items
ObjectDrawerItem[] drawerItem = new ObjectDrawerItem[3];
drawerItem[0] = new ObjectDrawerItem(R.drawable.ic_action_copy, "Create");
drawerItem[1] = new ObjectDrawerItem(R.drawable.ic_action_refresh, "Read");
drawerItem[2] = new ObjectDrawerItem(R.drawable.ic_action_share, "Help");
// Pass the folderData to our ListView adapter
DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.listview_item_row, drawerItem);
// Set the adapter for the list view
mDrawerList.setAdapter(adapter);
// set the item click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// for app icon control for nav drawer
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mDrawerTitle);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
if (savedInstanceState == null) {
// on first time display view for first nav item
selectItem(0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
// to change up caret
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
// navigation drawer click listener
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new CreateFragment();
break;
case 1:
fragment = new ReadFragment();
break;
case 2:
fragment = new HelpFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
}
*********** EDIT 1 ***********
I try this method:
I replace this part :
private void selectItem(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new CreateFragment();
break;
case 1:
fragment = new ReadFragment();
break;
case 2:
fragment = new HelpFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
with this:
private void selectItem(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
break;
case 1:
Intent intent = new Intent(this, MyCustomActivity.class);
startActivity(intent)
break;
case 2:
Intent intent2 = new Intent(this, MyCustomActivity.class);
startActivity(intent2)
break;
default:
break;
}
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
But when i try on my device, the button doesn'n work as if I had not binded action
*********** EDIT 2 ***********
public class MainActivity extends Activity implements View.OnClickListener {
// declare properties
private String[] mNavigationDrawerItemTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
// nav drawer title
private CharSequence mDrawerTitle;
// used to store app title
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// for proper titles
mTitle = mDrawerTitle = getTitle();
// initialize properties
mNavigationDrawerItemTitles = getResources().getStringArray(R.array.navigation_drawer_items_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// list the drawer items
ObjectDrawerItem[] drawerItem = new ObjectDrawerItem[3];
drawerItem[0] = new ObjectDrawerItem(R.drawable.ic_action_copy, "Create");
drawerItem[1] = new ObjectDrawerItem(R.drawable.ic_action_refresh, "Read");
drawerItem[2] = new ObjectDrawerItem(R.drawable.ic_action_share, "Help");
// Pass the folderData to our ListView adapter
DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.listview_item_row, drawerItem);
// Set the adapter for the list view
mDrawerList.setAdapter(adapter);
// set the item click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// for app icon control for nav drawer
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mDrawerTitle);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
if (savedInstanceState == null) {
// on first time display view for first nav item
selectItem(0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
// to change up caret
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
// navigation drawer click listener
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
#Override
public void onClick(View arg0) {
System.out.println("DEBUG"+arg0);
//ACTION, arg0 no value
}
}
Create a new Activity Extending your MainActivity which is having the Navigation Drawer.This new Activity will automatically have the navigation Drawer.
Check this answer for further details :
Same Navigation Drawer in different Activities
Did you try to inflate to a new Activity instead of creating a new Fragment in private void selectItem(int position) { ... } I mean, when you get the position, to create an Intent for the current activity Intent intent = new Intent(this, YourCustomActivity.class); and to navigate to it with startActivity(intent)

Why Sliding Menu Can't Close in Android

Please I have a problem, in my code like its nothing wrong, why when I select content on Sliding Menu, Sliding menus are not automatically covered? What's wrong with my code? I do not use a fragment only uses a switch to display the menu
MainActivity.java
public class MainActivity extends FragmentActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mDrawerItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
mDrawerItems = getResources().getStringArray(R.array.list);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// set a custom shadow that overlays the main content when the drawer oepns
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// Add items to the ListView
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mDrawerItems));
// Set the OnItemClickListener so something happens when a
// user clicks on an item.
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// Enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
// Set the default content area to item 0
// when the app opens for the first time
if(savedInstanceState == null) {
navigateTo(0);
}
}
/*
* If you do not have any menus, you still need this function
* in order to open or close the NavigationDrawer when the user
* clicking the ActionBar app icon.
*/
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
Intent i = new Intent(MainActivity.this, tentang.class);
startActivity(i);
}
if(mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
/*
* When using the ActionBarDrawerToggle, you must call it during onPostCreate()
* and onConfigurationChanged()
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
private class DrawerItemClickListener implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.v(TAG, "ponies");
navigateTo(position);
}
}
private void navigateTo(int position) {
Log.v(TAG, "List View Item: " + position);
switch(position) {
case 0:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame,
sejarah.newInstance(),
sejarah.sejarah).commit();
break;
case 1:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame,
pakaian.newInstance(),
pakaian.pakaian).commit();
break;
case 2:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame,
rumah.newInstance(),
rumah.rumah).commit();
break;
case 3:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame,
senjata.newInstance(),
senjata.senjata).commit();
break;
case 4:
Intent i = new Intent(MainActivity.this, lagu.class);
startActivity(i);
break;
case 5:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame,
musik.newInstance(),
musik.musik).commit();
break;
case 6:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame,
kesenian.newInstance(),
kesenian.kesenian).commit();
break;
}
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
}
you miss the the part drawer.closeDrawer(mDrawerList) or mDrawerLayout.closeDrawer(mDrawerList)

How to navigate to previous fragment using back-button within NavigationDrawer?

I know that similar questions have been asked before, but I can't seem to find exactly what I’m looking for. My problem is that my back button is currently exiting the app. What I’m trying to do is to make it navigate to the previous fragment. Like if you open fragment1 - > fragment2 and then press the back button it would take you back to fragment1.
My current code looks like this.
public class MainActivity extends FragmentActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPageTitles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
mPageTitles = getResources().getStringArray(R.array.menu_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// set a custom shadow that overlays the main content when the drawer
// opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
GravityCompat.START);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPageTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
)
{
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
// Sets the firstpage if no state is found
if (savedInstanceState == null) {
selectItem(0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content
// view
return super.onPrepareOptionsMenu(menu);
}
// Toogles the drawer menu
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return mDrawerToggle.onOptionsItemSelected(item);
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch (position) {
case 0:
KontaktInfoFragment kontakt = new KontaktInfoFragment();
fragmentTransaction.replace(R.id.content_frame, kontakt);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 1:
OmOssFragment omoss = new OmOssFragment();
fragmentTransaction.replace(R.id.content_frame, omoss);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 2:
MainScreenActivity mainscreen = new MainScreenActivity();
fragmentTransaction.replace(R.id.content_frame, mainscreen);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 3:
LoginFragment login = new LoginFragment();
fragmentTransaction.replace(R.id.content_frame, login);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
case 4:
ContactFormFragment form = new ContactFormFragment();
fragmentTransaction.replace(R.id.content_frame, form);
fragmentTransaction.addToBackStack("Replace");
fragmentTransaction.commit();
break;
}
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPageTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
}
When you press back button inside your fragment onBackPressed() method of your activity will be called if you have declared that..So handling back button for fragments within navigation drawer can be one in this way..
MainActvity
public static boolean isMainActivityShown ;
public static boolean isFragment1Shown=false ;
public static boolean isFragment2Shown=false ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isMainActivityShown=true //inside onCreate method put isMainActivityShown true
.
.
.
}
Fragment currentFragment = new Fragment1();
isMainActivityShown=false; //when moving to fragment1
isFragment1Shown=true;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();
#Override
public void onBackPressed() {
if(isMainActivityShown)
{
finish();
}
else if(isFragment1Shown)
{
//write the code to handle back button when you are in Fragment1
}
else if(isFragment2Shown)
{ //When you are in Fragment 2 pressing back button will move to fragment1
Fragment currentFragment = new Fragment1();
isFragment2Shown=false;
isFragment1Shown=true;
FragmentManager frgManager;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();
}
}
Fragment1
Fragment currentFragment = new Fragment2();
MainActivity.isFragment1Shown=false;
MainActivity.isFragment2Shown=true;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();

navigation drawer and fragment back stack handler

I keep reading about fragment and fragment back handling but still couldn't find a best solution here.
I have navigation drawer.
Lets pretend I have 2 items in my navigation drawer list (item1,item2)
when I click on item1 it's open A Fragment. in A Fragment after clicking in button opens B Fragment. So when B fragment is opened and I choose item2 from navigation drawer opens C Fragment.
And now when I press back button it should finish activity not go to B Fragment.
So in one word when I choose item1,item2 opens A fragment or C fragment, after pressing back button should finish activity but when opens B fragment(which is under item1) it have to go back to A Fragment
Please help it is very difficult for me. Thanks
public class MainActivity extends DefaultActivity {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggleWrapper mDrawerToggle;
private ListView mDrawerListView;
private TextView mTitle;
private Runnable mPendingRunnable;
private Handler mHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDrawerListView = (ListView) findViewById(R.id.left_drawer);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mFragmentManager = getSupportFragmentManager();
mHandler = new Handler();
LayoutInflater inflator = (LayoutInflater) this .getSystemService(LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.custom_view, null);
mTitle = (TextView)v.findViewById(R.id.title);
getSupportActionBar().setBackgroundDrawable(null);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
getSupportActionBar().setIcon(R.drawable.button_indicator_menu);
getSupportActionBar().setCustomView(v);
v.findViewById(R.id.menu).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!mDrawerLayout.isDrawerOpen(GravityCompat.START)){
mDrawerLayout.openDrawer(GravityCompat.START);
}else {
mDrawerLayout.closeDrawers();
}
}
});
mDrawerToggle = new ActionBarDrawerToggleWrapper(this, mDrawerLayout, R.drawable.transparent_gic, R.string.drawer_open, R.string.drawer_close){
public void onDrawerClosed(View view) {
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
mPendingRunnable = null;
}
}
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.addPartnerToggle(new ContentDisplaceDrawerToggle(this, mDrawerLayout, R.id.content_frame));
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerLayout.setDrawerListener(mDrawerToggle);
setLeftDrawerLeftMenu();
getFragment(getString(R.string.home));
setTitle(getString(R.string.home));
}
private void setLeftDrawerLeftMenu(){
final ArrayList<Item> items = new ArrayList<Item>();
items.add(new SectionItem(this,"icons_small_home",getString(R.string.home)));
items.add(new SectionItem(this,"icons_small_myacounts",getString(R.string.my_account)));
items.add(new EntryItem(getString(R.string.bonuses)));
items.add(new EntryItem(getString(R.string.account_recharge)));
items.add(new EntryItem(getString(R.string.tariff_plans)));
items.add(new EntryItem(getString(R.string.languages)));
EntryAdapter adapter = new EntryAdapter(MainActivity.this, items);
mDrawerListView.setAdapter(adapter);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
EntryItem item = (EntryItem) items.get(i);
setTitle(item.getTitle());
}
});
}
public void setTitle(final String title){
mTitle.setText(title);
mPendingRunnable = new Runnable() {
#Override
public void run() {
getFragment(title);
}
};
mDrawerLayout.closeDrawers();
}
public void getFragment(String name){
if(getString(R.string.orange_shops).equalsIgnoreCase(name)){
if (!(mSelectedFragment instanceof OrangeShopsFragment)){
addPage(new MyFragment(MainActivity.this),true);
}
}else if(getString(R.string.home).equals(name)){
addPage(new HomeFragment(MainActivity.this),false);
}else{
throw new RuntimeException("unknown fragment "+ name);
}
}
public void addPage(final DefaultFragment pDefaultFragment, final boolean isAddToBackStack){
FragmentTransaction transaction = mFragmentManager.beginTransaction();
transaction.replace(R.id.content_frame, pDefaultFragment);
if (isAddToBackStack) transaction.addToBackStack(null);
transaction.commitAllowingStateLoss();
}
}
It's not so difficult to clear the backstack.
Whenever the user clicks on any item on the drawer, just call
while(getSupportFragmentManager.popBackStackImmediate()){}
to clear what you had before.
edit:
I know it's a old question but I found a better/more efficient way of doing it using:
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
that was answered in the groups.google.com by one of the Android engineers, I replaced it on my app and the "clear stack" command works much faster now. Hope it helps.
I also faced this problem while working with fragments and navigation drawer. When we are navigating from one fragment to another fragment they all are added to same backstack. So that's why you are getting this problem. Inorder to overcome this problem i myself maintained back stack and handled the on backpressed method
If you post your code i will suggest a nice solution for your problem

DrawerLayout on click disabled after first event

I'm trying to implement a drawer layout in my app. I follow the tutorial on android developer site and all goes fine. I have only a "little" problem: I lunch the app, open the drawer layout and click on an element of the list view and all goes great, but when I try to open another time the drawer and click on one of his element I noticed that the element that I've first clicked is still clicked and i'm not able to click on any of the other elements.The drawer simply close without lunching any onClick events.
My code is:
public class Eventi extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.eventi);
mTitle = mDrawerTitle = getTitle();
mPlanetTitles = getResources().getStringArray(R.array.menu);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// set a custom shadow that overlays the main content when the drawer
// opens
// mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
// GravityCompat.START);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.listview_item, mPlanetTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_launcher, /* nav drawer image to replace 'Up' caret */
R.string.hello_world, /* "open drawer" description for accessibility */
R.string.hello_world /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.eventi, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content
// view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch (item.getItemId()) {
case R.id.action_settings:
// create intent to perform web search for this planet
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
// catch event that there's no activity to handle intent
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
Toast.makeText(this, R.string.hello_world, Toast.LENGTH_LONG)
.show();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
System.out.println("c2");
selectItem(position);
}
}
private void selectItem(int position) {
System.out.println("c");
final String[] classes = getResources().getStringArray(R.array.classi);
FragmentTransaction tx = getFragmentManager().beginTransaction();
tx.replace(R.id.drawer_layout,
Fragment.instantiate(Eventi.this, classes[position]));
tx.commit();
/*
* // update the main content by replacing fragments Fragment fragment =
* new PlanetFragment(); Bundle args = new Bundle();
* args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
* fragment.setArguments(args);
*
* FragmentManager fragmentManager = getFragmentManager();
* fragmentManager.beginTransaction() .replace(R.id.content_frame,
* fragment).commit();
*/
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
I took it from the Developer site so I don't understand wher is the error. Is there anyone who can help me?
Thanks in advance ;)
Take a look at my code:
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
switch (position) {
case 0:
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new MainActivityFragment())
.commit();
break;
case 1:
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new DbListViewFragment())
.commit();
break;
case 2:
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new StatisticsFragment())
.commit();
break;
case 3:
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new CalculatorFragment(), "calculator")
.commit();
break;
}
I am using a switch-case. position 0 is the very first item in my ListView inside the drawer.
The problem is that you are using
FragmentTransaction.replace(r.Id.drawer_layout,fragment).
don't attach a fragment directly to the drawerlayout element , try to add a framelayout as your main content container then attach the fragment to this framelayou.
Your xml content should look like this sudo one
<drawerlayout>
<framelayout Id:fragment_holder/> //attach fragment to this view
<ListView/> // your drawer ListView.
<drawerlayout/>

Categories

Resources