I have a fragment with a view and an options menu:
public class OfferingsFragment extends Fragment
{
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.offering_tiles, null);
...
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent intent = new Intent(getActivity(), SettingsActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
From the options menu, the user opens this preference fragment, which is hosted by the SettingsActivity:
public class SettingsActivity extends Activity {
private SettingsFragment settingsFragment = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settingsFragment = new SettingsFragment();
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settingsFragment)
.commit();
}
The view of the OfferingsFragment depends on one of the preferences. That is, after this preference has changed, the OfferingsFragment must be refreshed by calling onCreateView again. What I do is this:
Open preference screen from OfferingsFragment's option menu
Change preference
Return to OfferingsFragment
If I return to the OfferingsFragment via the Home Button (left arrow in ActionBar), then the OfferingsFragment gets refreshed by calling its onCreateView (which is the desired effect). However, if I return to the OfferingsFragment via the Back Button (on the device), onCreateView is NOT CALLED and thus the view is NOT re-created. What I want is that the view is also re-created when the user presses the Back Button. Any ideas how to achieve this?
What Happens
When you press Up button parent activity is called via startActivity which means a new instance is created by default.
When you press Back button current activity is finished and you're back in the previous activity and its already existing instance (it was in stopped state).
How To Deal With It
What I want is that the view is also re-created when the user presses the Back Button. Any ideas how to achieve this?
Start the settings activity via startActivityForResult:
public static final int RC_SETTINGS = 1;
private void startSettingsActivity() {
Intent i = new Intent(this, SettingsActivity.class);
startActivityForResult(i, RC_SETTINGS);
}
When the result comes back reattach the fragment. This will recreate its view hierarchy.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Call to super if you value your life. And want proper lifecycle handling.
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SETTINGS) {
// If we just came back from SettingsActivity...
// ...reattach fragment and trigger view recreation.
final FragmentManager fm = getFragmentManager();
final f = fm.findFragmentById(android.R.id.content);
fm.beginTransaction().detach(f).attach(f).commit();
}
}
Replace the fragment ID with whatever you used.
Pro tip
If your fragment is not misconfigured you should be able to call
public class SettingsActivity extends Activity {
private SettingsFragment settingsFragment = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
settingsFragment = new SettingsFragment();
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settingsFragment)
.commit();
} else {
settingsFragment = (SettingsFragment) getFragmentManager().findFragmentById(android.R.id.content);
}
}
}
This is both resourceful and practical as your original code would lose state (for example scroll position) on configuration change.
Related
I have a navigation drawer activity with fragments and I will send each fragment to an activity. I have a problem if I select option 3 of my menu that is a fragment that will send me to an activity, but when I return with the Back button, it sends me to option 1, what I want is that I return to option 3.
How can I change this?
I tried to do it by parentActivity but it did not work
Thank you.
My navigation drawer activitywithfragments
When I click on the button, it sends me to an activity that is this
And in the activity I have a toolbar to return and what I want is to return to option 3 and not to 1.
What do I need to do in my code or what can I place?
My fragment code option 3
public class Mis_Aliados extends Fragment {
Button boton;
public Mis_Aliados() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.persona_mi_perfil, container, false);
boton=view.findViewById(R.id.buton);
boton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), ActividadEx.class);
startActivity(intent);
}
});
return view;
}
}
My activity code
public class ActividadEx extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pruebaactividad);
Toolbar toolbarback=findViewById(R.id.include);
setSupportActionBar(toolbarback);
getSupportActionBar().setTitle("Activity");
ActionBar actionBar=getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
In your ActividadEx add this method to handle toolbar back button press
I'm putting 1 intent extra to make sure you want to open Option 3 when you are back to Navigation drawer Activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, NavgationDrawerActivity.class);
intent.putExtra("openOption3", true);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
On NavigationDrawerActivty inside onCreate()
you can check if Bundle has data or not. If its empty you can open Option1 fragment.
If it has data check it. and open Option3 Fragment.
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
if (bundle.getBoolean("openOption3", false)) {
//Use Fragment Transaction to Open Option 3 Fragment
} else {
//Open Option 1 Fragment Or any other Fragment
}
} else {
//Open Option 1 Fragment Or any other Fragment
}
Feel free to comment if you've any queries.
I'm learning Android development by creating a test project: Tic-tac-toe. My Tic-tac-toe app starts with a Main Menu activity with a Button that says New Game. After clicking New Game, an activity with a fragment containing a Tic-Tac-Toe game (in a GridLayout) launches. The user can play the game, but when they go back to the Main Menu, the game state is not saved.
I want to change this so that when the user goes back to the Main Menu, they will see a new Button called "Continue" (in addition to the "New Game" Button). Once the user clicks "Continue", the game they were playing before continues. If the click the "New Game" button, a new game will be launched like before.
By using the onSaveInstanceState method and a Bundle savedInstanceState, I was able to preserve the game state on orientation changes (by saving the data from the underlying TicTacToe class). My code below shows how I did that. I would like to do something similar this time again - I have read about it, but I don't quite understand the best way to start. Can anyone show me the right steps?
Note that I'm doing this programmatically (i.e. designing the layout outside the xml files)!
My MainMenu class:
public class MainMenu extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void startGame(View view) {
Intent intent = new Intent(this,MainGame.class);
startActivity(intent);
}
}
with a corresponding xml file activity_main_game:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/new_game"
android:onClick="startGame"
/>
</RelativeLayout>
Now my MainGame.class looks like this:
public class MainGame extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_game);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new BoardFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_game, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class BoardFragment extends Fragment {
public TicTacToe t = new TicTacToe(); //A class I wrote that launches a simple TicTacToe game
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null) {
t = new TicTacToe(savedInstanceState.getInt("TicTacToeData"),
);
}
//Graphics stuff here: variable rootView which contains the TicTacToe grid is defined
//and onClickListeners are added to the ImageViews in the GridLayout which makes corresponding
//changes to t.
return rootView;
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("TicTacToeData", t.getGameData());
}
}
}
Thanks for any help.
You have two options
SharedPreferences: you can use shaerdPreferences to store the state of the game. It would be stored also after the restart of the application.
start your game activity with startActivityForResult() and implementing onActivityResult on your parent activity.
There are 2 things you have to do:
Get notified within Main class when your MainGame Activity is closed
Update the UI to change the button text
To get notified within Main class:
You can start MainGame Activity using startActivityForResult instead of startActivity. Then override the onActivityResult method on Main class to be notified when the user close the MainGame.
Also you will have to modify MainGame to invoke setResult(int resultCode, Intent data) or setResult(int resultCode) method when the user click the back button (depending on whether you want to pass additional data back to the Activity.
Override the onBackPressed() method in your MainGame class to invoke the setResult method. E.g.
public void onBackPressed() {
setResult(RESULT_OK);
super.onBackPressed(); // otherwise your Activity won't be closed
}
Have a look at http://developer.android.com/reference/android/app/Activity.html#StartingActivities for a more detailed example
To Update the UI:
Save the button as a local variable (in your onCreate method)
Update the Button text MainGame Activity
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
// Update the button text to "Continue"
} else {
// Change the button text back to "New Game"
}
}
}
One possible solution is to have your MainGame Activity return the state of your game when it finishes. Then your MainMenu Activity can save that value and use it to start up a game in the same state.
For starters, you will want to start your game Activity in a way that enables it to return a value:
public class MainMenu extends ActionBarActivity {
...
public void startGame() {
Intent intent = new Intent(this, MainGame.class);
startActivityForResult(intent, 1);
}
}
Next you will want to make sure that your board Fragment returns the correct state whenever it is closed:
public class BoardFragment extends Fragment {
...
#Override
public void onPause() {
Intent result = new Intent();
result.putExtra("TicTacToeData", t.getGameData());
getActivity().setResult(Activity.RESULT_OK, result);
}
}
Afterwards you will want your menu Activity record the result:
public class MainMenu extends ActionBarActivity {
private int mPreviousGameState;
...
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
mPreviousGameState = 1;
}
}
}
Now you can pass in this state when you start your game Activity:
public class MainMenu extends ActionBarActivity {
...
public void continueGame() {
Intent intent = new Intent(this, MainGame.class);
intent.putExtra("TicTacToeData", mPreviousGameState);
startActivityForResult(intent, 1);
}
}
Now you will need a way to create a board that is already in a specific game state:
public class BoardFragment extends Fragment {
public TicTacToe t = null
...
public BoardFragment (int gameState) {
t = new TicTacToe(gameState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null) {
// recreate the board after an orientation change
t = new TicTacToe(savedInstanceState.getInt("TicTacToeData"));
} else if (t == null) {
// create a new board if this is a new game
// if this is a continued game, the board is already setup
t = new TicTacToe();
}
}
And lastly you will need to call the correct version of BoardFragment from your game:
public class MainGame extends ActionBarActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_game);
if (savedInstanceState == null) {
Intent intent = getIntent();
int gameState = intent.getIntExtra("TicTacToeData", -1);
if (gameState == -1) {
getSupportFragmentManager().beginTransaction().add(R.id.container, new BoardFragment()).commit();
} else {
getSupportFragmentManager().beginTransaction().add(R.id.container, new BoardFragment(gameState)).commit();
}
}
}
}
Another solution is to redesign your app to have only a single Activity (or ActionBarActivity) subclass and multiple Fragment subclasses for each screen you want to show. You can keep a reference to both fragments in your Activity. This will implicitly retain the state of the fragment which displays the game board.
In Android, when we replace a container view with a new fragment, we can use replace() and addToBackStack( ), so on pressing back button we goto previous fragment.
But what if the following occurs :
Activity1 (fragment1 -> fragment2 [calls startActivity for Activity2]) -> Activity2
Within Activity1, I can press back button to go from fragment2 to fragment1. But when fragment2 starts another activity, on pressing back button from Activity2, it takes me to fragment1 in Activity1. How can I make back button press from Activity2 come back to fragment2 in Activity1 ?
Code :
// In Activity1 - starts with a ListFragment
#Override
protected void onResume() {
super.onResume();
getFragmentManager().beginTransaction()
.replace(R.id.container, ListFragment.newInstance(0))
.commit();
}
// In Activity1 , each item in list replaces the container view
// with new fragment
#Override
public void onItemSelected(int position) {
if(position == 0) {
getFragmentManager().beginTransaction()
.replace(R.id.container, Example1_Fragment.newInstance(0))
.addToBackStack(null)
.commit();
}
....
}
// In Example1_Fragment
public class Example1_Fragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.example1_fragment, container, false);
Button btnIntent = (Button) view.findViewById(R.id.btnIntent);
btnIntent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction("com.android.test2.app.example1_action");
startActivityForResult(intent,1);
}
});
return view;
}
// this is why I want to come back to Example1_Fragment -
// the activity I start has to send a result back to
// the Example1_Fragment, but on back button, it takes me
// back to the ListFragment, and I cannot take any UI
// action (change to UI) in Example1_Fragment, as the
// ListFragment gets displayed - the onActivityResult of
// Example1_Fragment does get called
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && resultCode == Activity.RESULT_OK){
// do something
}
}
Do not replace Fragment1 in onResume() callback, this method will always be called when you come back to activity1, please do it in onCreate() callback.
You can manually set the back pressed calls inside of this method in your Second Activity. So that when you press back, you can find fragment 2 by its tag and add it back.
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
Intent i = new Intent(this, firstActivity.class);
startActivity(i);
FragmentTwo fragmentTwo = manager.findFragmentByTag("fragmentTwoTag");
manager.beginTransaction.replace(fragmentOne, fragmentTwo).addToBackStack(null).commit();
}
I got a situation here .
I have FragmentActivty which holds a Fragment . when i click on a button in Fragment i am going to a Activty . when i reach the activity i do something which will affect the data displayed in Fragment where i came from. So in order to bring that changes in fragment i would like to give a callback from the Activity to Fragment. First i thought of implementing onActivityResult. But i realized it's not what i needed.
Is my approach is wrong?? Please guide me
MyActivity extends FragmentActivity
MyActivity holds
MyFragment extends Fragment
From here i'm going to
SecondActivity extends Activity
from SecondActivity i need to get a callback to MyFragment . Is there anything wrong with my approach ??
EDIT:
public class MainActivity extends FragmentActivity {
private FrameLayout frameLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frameLayout = (FrameLayout) findViewById(R.id.framelayout);
loadFragment();
}
#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;
}
private void loadFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
MyFragment myFragment = new MyFragment();
fragmentTransaction.add(R.id.framelayout, myFragment);
fragmentTransaction.commit();
}
}
MyFragment.java
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view, container, false);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
callActivity();
}
});
return view;
}
private void callActivity() {
Intent intent = new Intent(getActivity(), SecondActivity.class);
startActivityForResult(intent, 10);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
Log.e("MyFragment Inside", "Onresultttt");
if (requestCode == 10) {
if (resultCode == Activity.RESULT_OK) {
Log.e("Result code", Activity.RESULT_OK + " okkk");
}
if (resultCode == Activity.RESULT_CANCELED) {
Log.e("Result code", Activity.RESULT_CANCELED + "cancelll inside fragment");
}
}
}
}
SecondActivity.java
public class SecondActivity extends Activity {
private static final String TAG = "second activity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity_view);
}
#Override
public void onBackPressed() {
// super.onBackPressed();
Intent intent = new Intent();
setResult(RESULT_CANCELED, intent);
Log.e(TAG, "result setted");
finish();
}
}
Refer this question it will help you understand what is happening:
onActivityResult is not being called in Fragment
If I understand your situation correctly, then the correct way of handling the communication is to have SecondActivity pass back information to MyActivity, which will in turn configure it's instance of MyFragment directly. You don't want to be accessing Fragments from Activities unless the Fragment is attached to the Activity.
As for how to do the communication, as you suggested, one way of doing it would be through the use of startActivityForResult(). See this answer for more details: How to manage `startActivityForResult` on Android?
Just a note about startActivityForResult(). If you are calling it from the Fragment then your Fragment will receive the result, not your Activity. There are also some other issues with calling startActivityForResult() from a Fragment, so I would generally recommend that you instead call it from the Activity and therefore handle the result from the Activity.
Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, INTENT_CODE);
The best practice way of communicating from a Fragment to an Activity is by defining an Interface in the Fragment, which the Activity implements.
public class MyFragment extends Fragment {
public interface MyFragmentListener() {
public void onMyFragmentEvent();
}
public void startTheActivityForResult() {
((MyFragmentListener)getActivity()).onMyFragmentEvent();
}
}
public class MainActivity extends FragmentActivity implements MyFragmentListener{
#Override public void onMyFragmentEvent() {
}
}
The Fragment then simply casts the reference to the Activity it is attached to, knowing that the Activity must implement the Listener, thus allowing you to reuse the Fragment in other Activities.
I have an app that uses SherlockActionBar and switches between dynamic fragments through ActionItems in the Action Bar.
The problem is that i can't save the fragment states and their UI data.
This is the FragmentActivity:
public class MainActivity extends SherlockFragmentActivity {
private LocationFragment locationFragement;
private HomeFragment homeFragment;
private SettingsFragment settingsFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
locationFragement = new LocationFragment();
homeFragment = new HomeFragment();
settingsFragment = new SettingsFragment();
}
#Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
getSupportMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
FragmentManager fragManager = getSupportFragmentManager();
FragmentTransaction fragTransaction = fragManager.beginTransaction();
switch (item.getItemId()){
case R.id.home:
fragTransaction.replace(android.R.id.content, homeFragment);
break;
case R.id.location:
fragTransaction.replace(android.R.id.content, locationFragement);
break;
case R.id.settings:
fragTransaction.replace(android.R.id.content, settingsFragment);
break;
}
fragTransaction.commit();
return true;
}
Firstly, I tried to call to a single instance of the fragments, only to encounter NullPointerExceptions every time i did in the onOptionsItemSelected switch block
fragTransaction.replace(android.R.id.content, myFragmentClassName);
while the fragment instantiation was under
if(savedInstanceState == null){
locationFragement = new LocationFragment();
homeFragment = new HomeFragment();
settingsFragment = new SettingsFragment();
}
The fragments would not have created under orientation change obviously, and i couldn't figure anyway i could keep them instantiated. So i decided to create them anew every onCreate (which is bad but i wanted something to work) and save the UI data just to pass it back to the fragment.
This is one of the fragments, the other 2 are the same:
public class LocationFragment extends SherlockFragment {
private View myView;
private CheckBox myCheckBok;
#Override
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
Log.d("LocationFragment", "onCreate running");
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("LocationFragment", "onCreateView running");
myView = inflater.inflate(R.layout.map_fragment, container, false);
myCheckBok = (CheckBox) myView.findViewById(R.id.mapFragmentCheckBox);
if(savedInstanceState != null){
myCheckBok.setChecked(savedInstanceState.getBoolean("isChecked"));
}
return myView;
}
#Override
public void onResume()
{
Log.d("LocationFragment", "onResume running");
super.onResume();
}
#Override
public void onPause() {
Log.d("LocationFragment", "onPause running");
super.onPause();
}
#Override
public void onSaveInstanceState(Bundle outState) {
boolean isChecked = myCheckBok.isChecked();
outState.putBoolean("isChecked", isChecked);
Log.d("LocationFragment", "onSaved Instant running");
super.onSaveInstanceState(outState);
}
I'm saving the checkbox's state, when i pass through the icons the checkbox state is saved and also through orientation change. BUT, when i change orientation, press another icon (or press the same one) and return to my fragment, the state isn't saved. I realized this is caused due to onSavedInstanceState not running when i change to another fragment (thus not saving or passing the checkBox data).
I haven't found answers anywhere on how to save correctly UI data from fragments (just through savedInstanceState doesn't cut it for my purposes) or how to manage several fragment instantiations while changing them. I know that each time i change a fragment, all it's data
is saved automatically by the system, but can't seem to get it to work.
Please help.
It's not part of the problem but you should be aware that the use of onSaveInstanceState is not needed for saving a View state. Android does that for you already as long as there's an ID to the View.
Seems like the problem you are facing is that you are not restoring the fragments from their FragmentManager. The fragments are there, but you simply didn't go to the FragmentManager and brought them once the onCreate has happened again.
This code should go in the onCreate:
// Try and fetch the fragments from the manager
locationFragement = fragmentManager.findFragmentByTag(LOCATION_FRAGMENT_TAG);
homeFragment = fragmentManager.findFragmentByTag(HOME_FRAGMENT_TAG);
settingsFragment = fragmentManager.findFragmentByTag(SETTINGS_FRAGMENT_TAG);
// If the fragment weren't found - meaning it's the first time the activity was
// started, create them
if (locationFragement == null) locationFragement = new LocationFragment();
if (homeFragment == null) homeFragment = new HomeFragment();
if (settingsFragment == null) settingsFragment = new SettingsFragment();
And, whenever you are adding/removing/replacing a fragment, make sure to add him with the TAG, i.e.
// EXAMPLE HOW TO USE A REPLACE WITH A TAG
getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
locationFragement, LOCATION_FRAGMENT_TAG);
Does that work?