i am using navigation drawer in my android app..
Each of fragment contains async task which getting data from internet and displaying in custom list.
Here is code for selecting fragment:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
String TAG=null;
switch (position) {
case 0:
fragment = new HomeFragment();
TAG=new String("Home");
break;
case 1:
// fragment = new BlogsFragment();
fragment = new BlogsFragment();
break;
case 2:
// fragment = new NewsFragment();
fragment = new NewsFragment();
break;
case 3:
fragment = new TransferFragment();
break;
case 4:
fragment = new FixturesFragment();
break;
case 5:
fragment = new FeedFragment();
break;
case 6:
// fragment = new TwitterFragment();
fragment = new TwitterFragment();
break;
case 7:
// fragment = new FacebookFragment();
fragment = new FacebookFragment();
break;
case 8:
// fragment = new BookmarkFragment();
fragment = new BookmarkFragment();
break;
default:
break;
}
if (fragment != null) {
ft.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
But when i am switching between fragments an async task started loading data again..
So how to save state of fragment
I tried all the possible solution on stackoverflow
please help me
You can only save the state when your configuration changes or any other conditions. In your case each time you are loading the new fragment due to which it again resumes its life-cycle.
Check this
I think you need to cache/store the server response (async task result) for every visited fragment. If its JSON you could store it as string in SharedPrefs and then just take it back from there. This also assumes some expiration time for cashed responses to refresh it.
Since you do
ft.replace(R.id.frame_container, fragment).commit();
you destroy previously shown fragment completely. You could also play with addToBackStack() instead of replace or with retainInstance state.
Related
I have used the following codings:
For Custom Navigation Drawer:
http://www.tutecentral.com/android-custom-navigation-drawer/
For Google Map:
http://wptrafficanalyzer.in/blog/showing-nearby-places-with-photos-at-any-location-in-google-maps-android-api-v2/
I'm new in android so please tell me how to link the the custom navigation drawer with google map.
I think you didn't get the answer for this question. If you post your code, i can be more helpful. but, for now, I think you need to call MapFragment in your NavigationDrawer Activity.
If you need the map only for one fragment, I suggest you to use a switch statement.
Following shows a sample code.
private void updateDisplay(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new MapFragment();
break;
case 1:
fragment = any of your fragment();
break;
case 2:
fragment = any of your fragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
setTitle(menutitles[position]);
mDrawerLayout.closeDrawer(mLenear);
}
else {
// error in creating fragment
Log.e("Extract", "Error in creating fragment");
}
}
Hope this helps.
okay i know there are other questions that on first glance make this one look like a duplicate, but none of these answers work in my case,
What i want is the first fragment displayed to be like a Main Activity in respect to how the back button works, i need whichever fragment i choose from my navigation drawer to go back to the first fragment when the back button is pressed then a user would quit the app by pressing it again.
So ive tried using addToBackStack and when i move to another fragment if i press the back button it comes back to my first fragment (exactly as i want) but pressing the back button again leaves me with a white screen (i wonder if this is due to the transaction animation im using which ive included below) so to get around this i tried overriding the back button and throwing in a call to finish(); but this causes whichever fragment im in to finish instead of going back to the first fragment, ive tried a handful of workarounds from the above mentioned link and many others but cannot find a decent fix any suggestions?
here is my Main Activity displayView
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new FirstFragment();
break;
case 1:
fragment = new glideFrag();
break;
case 2:
fragment = new secondGlideFrag();
break;
case 3:
fragment = new thirdGlideFrag();
break;
case 4:
fragment = new forthGlideFrag();
break;
case 5:
fragment = new lgFrag();
break;
case 6:
fragment = new cyanFrag();
break;
case 7:
fragment = new sonyFrag();
break;
case 8:
fragment = new SecondFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.pop_enter,R.anim.pop_exit);
//fragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.frame_container, fragment).addToBackStack("first Fragment").commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
i found this that looks like a great way around it
private boolean popNext = false;
if(popNext){
if(position == INITIAL_POSITION){
onBackPressed();
mDrawerLayout.closeDrawer(mDrawerList);
popNext = false;
return;
}
getSupportFragmentManager().popBackStackImmediate();
}
else{
if(position == INITIAL_POSITION){
mDrawerLayout.closeDrawer(mDrawerList);
return;
}
popNext=true;
}
but im still fairly new to android and im not sure what to set INITIAL_POSITION to, I tried
private static final INITIAL_POSITION = 0;
but without any luck
When adding the initial fragment, you must not add it to the back stack.
You must only do it for the next ones. When the back stack will be empty, the Activity will just finish.
Edit: Here is an explanation of the problem so you can figure out how to fix it:
Each time you add a fragment transaction to the back stack, you allow the user to revert it by pressing the back button and the Activity will return to the state it was before the transaction. If the initial fragment is added to the back stack, then when the user press back, the screen becomes blank, because there was nothing displayed before you added the initial fragment. That's why the initial fragment transaction which adds the first visible fragment to your Activity must not be added to the back stack. Usually you initialize the initial fragment like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState == null) {
Fragment fragment = new FirstFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.frame_container, fragment)
.commit();
}
}
BladeCoders answer was more trying to tell me how the backstack works rather than answering my question, i ended up not adding any fragments to the back stack, .addToBackStack(null), and overriding back button in MainActivity, feels like a little bit of a hack but works perfectly
#Override
public void onBackPressed() {
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() < 1){
Fragment fragment = new FirstFragment();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.enter, R.anim.exit,
R.anim.pop_enter, R.anim.pop_exit);
getSupportActionBar().setTitle(mDrawerTitle);
fragmentTransaction.replace(R.id.frame_container,
fragment).addToBackStack("first").commit();
}else{
finish();
}
}
You can do it even with out backstack its just my point of view to simplify so that it can help some one.
#Override
public void onBackPressed(){
Fragment f = getSupportFragmentManager().findFragmentById(R.id.container_body);
if(f.getClass().getName().equals(HomeFragment.class.getName())){ // here HomeFragment.class.getName() means from which faragment you actually want to exit
finish();
}else{
displayView(0); //were you want to go when back button is pressed
}
}
private void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new HomeFragment();
title = getString(R.string.app_name);
break;
case 1:
fragment = new OffersFragment();
title = getString(R.string.nav_item_offers);
break;
case 2:
fragment = new NotificationFragment();
title = getString(R.string.nav_item_notifications);
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle(title);
}
}
I'm developing an android application, I have a problem with the changing of back button function. How i can "replace" the default action of this button ?
I would realize a simple function that allow the user to return to the previous fragment when back button is pressed, for example :
[Main Fragment] ----> [2nd Fragment]
[2nd Fragment] <---- [Main Fragment]
I have read some question like this, but i don't understand how to solve my problem.
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment(getApplicationContext());
break;
case 1:
fragment = new FindPeopleFragment();
break;
case 2:
fragment = new PhotosFragment();
break;
case 3:
fragment = new CommunityFragment();
break;
case 4:
fragment = new PagesFragment();
break;
case 5:
fragment = new WhatsHotFragment();
break;
default:
break;
}
This is the part of my code where i call the "new fragment".
When i start up my application a new fragment is created (HomeFragment), in this frag i create a new fragment (Fragment_Detail).
What that i want is return from Fragment_Detail to HomeFragment.
I hope I was explanatory
Just add the addToBackStack(null). It will automatically go to the previous fragment loaded in stack.
HomeFragment fragment = new HomeFragment();
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction()
.replace(R.id.content, fragment,TAG)
.commit();
Refer addToBackStack() and refer this answer.
Refer the docs
You should take a look at the example: http://developer.android.com/training/implementing-navigation/temporal.html#back-fragments
I am using fragment in my application. When I change the orientation the fragment removes and my main activity gets visible from which I have added this fragment. below is the code -
Fragment fragment = null;
switch (position) {
case 0:
fragment = new ManageDataFragment();
break;
case 1:
fragment = new DownloadFragment();
break;
case 2:
fragment = new UserInfoFragment();
break;
case 3:
fragment = new AboutAppFragment();
break;
case 4:
fragment = new ShareAppFragment();
break;
case 5:
fragment = new SettingsFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
setTitle(menutitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
I am using this fragment from navigationDrawer like in Gmail application.
What should I do that my fragment remains even I change the orientation of device?
Thanks in Advance
I don't think the accepted answer is the correct so I'm writing this one:
When replacing the fragment you should use the method replace with three arguments so you can find your fragment later:
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment, TAG_FRAGMENT).commit();
Where TAG_FRAGMENT is some string tag.
Then in onCreate if the activity was restarted you can find your fragment and add it to the container:
if(savedInstanceState != null) {
fragment = getFragmentManager().findFragmentByTag(TAG_FRAGMENT);
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment, TAG_FRAGMENT).commit();
}
I had exactly the same problem as mentioned above and I fixed it in the AndroidManifest by adding this:
<activity
...
android:configChanges="orientation|screenLayout|screenSize|layoutDirection">
Hope this helps!
Probably should save position using onSaveInstanceState() and test the bundle argument to onCreate().
I'm using the NaviagationDrawer with the Fragment.
Now in MainActivity, I open the various fragment but one of the lines must open an Activity.
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new InFragment();
break;
case 2:
fragment = new RiFragment();
break;
case 3:
fragment = new RieFragment();
break;
case 4:
fragment = new PagesFragment();
break;
case 5:
fragment = new WhatsHotFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
In case 4, I would like to open an activity as I do?
If you want to open a new activity in case 4:, you can simply start a new activity with an Intent as you normally would.
...
case 4:
Intent intent = new Intent(this, MyActivity.class);
startActivity(intent);
break;
...
You would also want to change your if/else block on the bottom to avoid logging an error when you start a new activity (since your fragment variable would be null in this case).