Android Fragment forgets button - android

My fragment initializes the button, i can see that in the debugger.
When i call the method setButtonText from the activity that has the fragment in it's layout, the button becomes null. I've looked on the internet but so far i didn't found any solution
public class PrepareTrainingFragment extends Fragment
{
private Button button;
private TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.preparetrainingfragment, container, false);
button=(Button) v.findViewById(R.id.ptfragmentbtn);
Log.w("button init","button init");
return v;
}
public void setButtonText(String text)
{
button.setText(text);
}
in the class that encapsulates the fragment:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); //hide navigation bar temporarily
driverFragment=new PrepareTrainingFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, driverFragment);
driverFragment.setButtonText("hello");
}

A FragmentTransaction is not executed in real time, you have to call boolean result = fragmentTransaction.executePendingTransactions(); before updating your button. Also, why dont you update the button within your Fragment ?

Related

App title doesn't change after returning to previous fragment

I've been developing an android app which I included the default Navigation-Drawer from Android Studio and so on. In my home fragment, I've implemented CarViews, and then set those cardview(s) OnClickListener to replace the fragment with traditional procedure.
After the fragment replacement and new page comes, I wanted to change the Actionbar title.
So in the onCreateView(...) method, I tried,
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("B");
It worked. But after pressing the hardware back button to go back to the stacked fragment, the title remains changed & it doesn't change to "Home" again. I've tried other ways. Here's my following codes. Thanks in advance.
public class HomeFragment extends Fragment implements View.OnClickListener {
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar()).setTitle("Home");
CardView cardView1 = root.findViewById(R.id.doctor_on);
CardView cardView2 = root.findViewById(R.id.ambulance_e);
CardView cardView3 = root.findViewById(R.id.maintainance_s);
cardView1.setOnClickListener(this);
cardView2.setOnClickListener(this);
cardView3.setOnClickListener(this);
return root;
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.doctor_on:
FragmentTransaction fragmentTransaction = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment1 = new doctors();
fragmentTransaction.replace(R.id.container1, fragment1).addToBackStack(getString(R.string.menu_home)).commit();
return;
case R.id.ambulance_e:
//Put Actions
FragmentTransaction fragmentTransaction2 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment2 = new ambulance();
fragmentTransaction2.replace(R.id.container1, fragment2).addToBackStack(getString(R.string.menu_home)).commit();
return;
case R.id.maintainance_s:
//Put Actions
FragmentTransaction fragmentTransaction3 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment3 = new maintanance();
fragmentTransaction3.replace(R.id.container1, fragment3).addToBackStack(getString(R.string.menu_home)).commit();
return;
}
}
#Override
public void onResume() {
super.onResume();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Home");
}
}
To the next fragment(where I change the titlebar and pressed back button):
public class doctors extend Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("B");
View root = inflater.inflate(R.layout.fragment_doctors, container, false);
return root;
}
}
And in the doctors Fragment... Should fix the title error.
#Override
public void onDestroyView() {
super.onDestroyView();
Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity()))
.getSupportActionBar())
.setTitle(getString(R.string.your_title_here));
}
You have to override the method onBackPressed() and write the code:
#Override
public View onBackPressed(){
//Here goes the code that head back to your main fragment
FragmentTransaction fragmentTransaction3 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment3 = new maintanance();
fragmentTransaction3.replace(R.id.container1, fragment3).addToBackStack(getString(R.string.menu_home)).commit();
}
}`
Add below code in Home Fragment...
#Override
public void onHiddenChanged(Boolean hidden) {
super.onHiddenChanged(hidden);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Home");
}

findViewById in different layout (cannot find BottomNavigationView)

I'm doing an app so when you click on a login button, it will then display a screen with a bottom menu. But I'm having problems with setting the listener to the items in the menu. The problem is when I try to use findViewById to find my BottomNavigationView it will look for it in my activity_main instead of the fragment (welcome_fragment) where I have put it, because I only want it to show when someone has logged in. And therefore I will get null as the BottomNavigationView.
I have tried setting setContentView(R.layout.welcome_fragment) in my method "welcomePage", which does make it so that so that it will find it and it won't be null. However this results in a lot of other errors such as
" No view found for id 0x7f080032 (com.example.MyAPP:id/container) for fragment WelcomePage{9547e9f #1 id=0x7f080032}", so I don't believe it to be the right way to go about it.
Here is my MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getFragmentManager();
Login loggingIn= new Login();
fm.beginTransaction().replace(R.id.container, loggingIn).commit();
}
//When button is pressed we get into this function
public void finishProcess(){
WelcomePage wp = new WelcomePage();
FragmentManager fm = getFragmentManager();
fm.beginTransaction().addToBackStack(null);
fm.beginTransaction().replace(R.id.container, wp).commit();
try {
//Here is where I get null, because we are looking in activity_main
BottomNavigationView bottomNav=findViewById(R.id.bottomnavigate);
bottomNavigation.setOnNavigationItemSelectedListener(menuListener);}
catch (Exception e) {
System.out.println(e);
}
}}
//Have tried this one and it works fine
private BottomNavigationView.OnNavigationItemSelectedListener menuListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {...}
}
Here is my WelcomeFragment:
public class WelcomePage extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.welcome_fragment, container, false)}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Here is my layout to the welcome_fragment:
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WelcomePage"
android:background="#drawable/welcomegradient">
<FrameLayout
android:id="#+id/showing_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottomnavigate">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottomnavigate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/mymenu"
android:background="?android:attr/windowBackground" />
</RelativeLayout>
As I mentioned earlier the problem is that findViewById can't find the BottomNavigationView because it is looking in the activity_main instead of welcome_fragment and I don't want to put my menu in activity_main because I only want to display it when a user has logged in. How do I fix this problem?
Try this, it should work.
WelcomePage
public class WelcomePage extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.welcome_fragment, container, false);
//Have tried this one and it works fine
BottomNavigationView.OnNavigationItemSelectedListener menuListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {...}
BottomNavigationView bottomNav = view.findViewById(R.id.bottomnavigate);
bottomNav.setOnNavigationItemSelectedListener(menuListener);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fm = getSupportFragmentManager();
Login loggingIn= new Login();
fm.beginTransaction().replace(R.id.container, loggingIn).commit();
}
//When button is pressed we get into this function
public void finishProcess() {
WelcomePage wp = new WelcomePage();
fm.beginTransaction().addToBackStack(null);
fm.beginTransaction().replace(R.id.container, wp).commit();
}
}

Android FragmentManager for same Activity hide() doesnt work

Hi guys im working on my MainActivity and I am dealing with the following problem:
In my MainActivity I have 3 buttons(button1, button2, button3). With each I can add a Fragment(Fragment2, Fragment1, ProfileFragment) to my container. Everytime a button is pressed, it checks the Fragments if there is already anotherone visible.
If yes, FragmentManager().beginnTransaction().fragment.hide() should hide it.
Then it checks if the fragment bound to the button already exists.
If no, it adds it.
If yes, it should make the existing hidden fragment visible again with FragmentManager().beginnTransaction().fragment.show()
Now: If I press button2 as the first when I start my App everything works fine and I can infinitely switch between the fragments.
But: If I press button1 as the first, and then switch to button2 or button3, the fragment bound to button1 (m2fragment) can't be shown again. It just shows m1fragment (which should be hidden when I press button1)
The same happens if I press button3 as the first. Everytime I try to switch back to button3(profileFragment) it just shows m1fragment.
May be there a problem with the googleMap which I call from the xml from m2Fragment??
Anyone can see where I made (a) mistake(s) ? I would be really glad since I am dealing with this for several days now.
Thank you all !
Cut from my MainActivity:
public class MainActivity extends FragmentActivity implements ProfileFragment.OnFragmentInteractionListener,
OfferFragment.OnFragmentInteractionListener, MapsFragment.OnFragmentInteractionListener, OpenerFragment.OnFragmentInteractionListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
protected int fragment1Open = 0;
protected int fragment2Open = 0;
protected int profileFragmentOpen = 0;
Fragment1 m1Fragment = new Fragment1();
Fragment2 m2Fragment = new Fragment2();
ProfileFragment mProfileFragment = new ProfileFragment();
OpenerFragment mOpenerFragment = new OpenerFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState==null) {
getFragmentManager().beginTransaction().add(R.id.container,mOpenerFragment).commit();
}
final Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//check fragments
if(mOpenerFragment.isVisible()) {
getFragmentManager().beginTransaction().remove(mOpenerFragment).commit();
Log.d("button1", "remove OpenerFragment");
}
if(m1Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m1Fragment).commit();
}
if(mProfileFragment.isVisible()) {
getFragmentManager().beginTransaction().hide(mProfileFragment).commit();
}
if(fragment2Open==0) {
fragment2Open=1;
getFragmentManager().beginTransaction().add(R.id.container, m2Fragment).commit();
} else {
getFragmentManager().beginTransaction().show(m2Fragment).commit();
}
}
});
final Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//hide other fragments
if(mOpenerFragment.isVisible()) {
getFragmentManager().beginTransaction().remove(mOpenerFragment).commit();
}
if(mProfileFragment.isVisible()) {
getFragmentManager().beginTransaction().hide(mProfileFragment).commit();
}
if(m2Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m2Fragment).commit();
}
if(fragment1Open==0) {
fragment1Open=1;
getFragmentManager().beginTransaction().add(R.id.container, m1Fragment).commit();
} else {
getFragmentManager().beginTransaction().show(m1Fragment).commit();
}
}
});
final Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//hide other fragments
if(mOpenerFragment.isVisible()) {
getFragmentManager().beginTransaction().remove(mOpenerFragment).commit();
}
if(m1Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m1Fragment).commit();
}
if(m2Fragment.isVisible()) {
getFragmentManager().beginTransaction().hide(m2Fragment).commit();
}
//open fragment
if(profileFragmentOpen==0) {
profileFragmentOpen=1;
getFragmentManager().beginTransaction().add(R.id.container, mProfileFragment).commit();
} else {
getFragmentManager().beginTransaction().show(mProfileFragment).commit();
}
}
});
mProfileFragment and m2Fragment use identically onCreate and onCreateView methods:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.fragment_profile, container, false);
return rootview;
}
m1Fragment has the same methods, but gets a googleMaps fragment from its xml file.
m1Fragment:
public class Fragment1 extends Fragment implements OnMapReadyCallback {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapFragment mapFragment=(MapFragment) getFragmentManager().findFragmentById(mapid);
if (mapFragment==null) {
mapFragment = MapFragment.newInstance();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, mapFragment);
fragmentTransaction.commit();
mapFragment.getMapAsync(this);
}
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap map) {
//right upper corner, location layer activated
map.setMyLocationEnabled(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_maps, container, false);
return rootView;
}
fragment_1.xml:
<fragment
android:id="#id/mapid"
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
MapFragment mapFragment=(MapFragment) getFragmentManager().findFragmentById(mapid);
in this line your actually tring to get the parent's fragmentManager (in your case the activity),and fail to find the fragment.
and then in this line:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, mapFragment);
fragmentTransaction.commit();
you are adding to the parent FragmentManager.
a quick to solution is to replace getFragmentManger() with getChildFragmentManager, which refers to the fragment's FragmentManager.
Maybe you should try to use :
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
With fragment_container as FrameLayout in your activity?
I'm not 100% sure, but i think it'll avoid such issues
I just solved it:
Withing my MapsFragment class I instantiated a googleMaps fragment "twice". Trying to hide the mapFragment I just hid one of them, leaving the other one visible in front.
For people having similar issues here my solution:
I erased the
<fragment
android:id="#id/mapid"
class="com.google.android.gms.maps.MapFragment"/>
from the xml layout file.
And inside the MapsFragment class I changed
MapFragment mapFragment=(MapFragment) getChildFragmentManager().findFragmentById(mapid);
to
MapFragment mapFragment = MapFragment.newInstance();
getChildFragmentManager().beginTransaction().add(R.id.framLay, mapFragment).commit();
Now I put one clean Instance of MapFragment into my FrameLayout and it works properly.

Multiple calls to FragmentTransaction.replace() - only one works after orientation change

I am using the following code to populate my UI with 2 fragments, the containers are FrameLayout's defined in XML. This first time this code is called i.e. when the app starts, it works fine, and both my fragments are displayed as expected. However after a configuration change(specifically, orientation), only the first fragment in the transaction is shown.
I don't think it's an issue with the fragments themselves, because if I reverse the code so one replace is called before the other or vice versa, that fragment will be displayed. So for example with the snippet from below as a guide, if I swap the mSummary and mDetails replace calls, then mDetails will be displayed and mSummary won't.
It's always the second one in the block that is missing.
// Using tablet layout
} else {
FragmentManager fm = super.getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.summary_container, mSummaryFragment);
ft.replace(R.id.details_container, mDetailsFragment);
ft.commit();
}
I'm saving the fragments in onSaveInstanceState and restoring them from the Bundle savedInstanceState when the activity is recreated. I also tried breaking the transaction into two pieces by calling commit() and then getting another FragmentTransaction object but no joy there.
So for anyone coming across this at a later stage...
I finally manage to fix this by creating a new instance of the fragment and restoring it's state using a Fragment.SavedState object. So:
if (mSummaryFragment.isAdded() && mDetailsFragment.isAdded()) {
Fragment.SavedState sumState = getSupportFragmentManager().saveFragmentInstanceState(mSummaryFragment);
Fragment.SavedState detState = getSupportFragmentManager().saveFragmentInstanceState(mDetailsFragment);
mSummaryFragment = new SummaryFragment();
mSummaryFragment.setInitialSavedState(sumState);
mDetailsFragment = new DetailsFragment();
mDetailsFragment.setInitialSavedState(detState);
}
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.add(R.id.summary_container, mSummaryFragment);
ft.add(R.id.details_container, mDetailsFragment);
ft.commit();
I do not understand why this works and the old method doesn't, however this may be helpful for someone else.
this should work and orientation change will not affect the fragment., if you face any problem just let me know.
public class MainActivity extends FragmentActivity {
Fragment fragment = new Fragment1();
Fragment fragment2=new Fragment2();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = super.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame1, fragment);
ft.replace(R.id.frame2, fragment2);
ft.commit();
}
public void onSaveInstanceState(Bundle outState){
getSupportFragmentManager().putFragment(outState,"fragment1",fragment);
getSupportFragmentManager().putFragment(outState,"fragment2",fragment2);
}
public void onRetoreInstanceState(Bundle inState){
fragment = getSupportFragmentManager().getFragment(inState,"fragment1");
fragment2 = getSupportFragmentManager().getFragment(inState,"fragment2");
}
class Fragment1 extends Fragment{
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.summary_view,container,false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
class Fragment2 extends Fragment{
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.detail_view,container,false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
}

Fragment replaced by first one on orientation change

I have a problem with one thing - when I change orientation my second fragment, which is active at the moment, replaces by first fragment. I have never so such a behaviour, how can If fix it?
MainActivity:
public class MainActivity extends SherlockFragmentActivity implements onDialogClickListener, ITaskLoaderListener {
FragmentManager fm;
public ActionBar actionBar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pager_layout);
fm = getSupportFragmentManager();
actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentTransaction ft = fm.beginTransaction();
ft.add(android.R.id.content, new FirstActivity.FirstFragment(), "loan").commit();
}
}
FirstFragment:
public class FirstActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "here");
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentById(android.R.id.content) == null) {
FirstFragment first = new FirstFragment();
fm.beginTransaction().add(android.R.id.content, first).commit();
}
}
public static class FirstFragment extends SherlockFragment implements OnClickListener, OnItemClickListener {
private static final String TAG = "LoanFragment";
private View rootView;
private Button bExtend;
private FragmentManager fm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (session.hasLoan()) {
rootView = inflater.inflate(R.layout.fragment_loan, container, false);
bExtend = (Button) rootView.findViewById(R.id.b1);
return rootView;
}
}
#Override
public void onClick(View v) {
FragmentTransaction ft = fm.beginTransaction();
switch (v.getId()) {
case R.id.b1:
ft.add(android.R.id.content, new SecondActivity.SecondFragment(), "second").addToBackStack(null).commit();
break;
}
Second Fragment:
public class SecondActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentById(android.R.id.content) == null) {
SecondFragment second = new secondFragment();
fm.beginTransaction().add(android.R.id.content, second).commit();
}
}
public static class SecondFragment extends SherlockFragment {
private View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_extend, container, false);
return rootView;
}
That`s to say when I am in second fragment and try to change orientation then my second fragment will replaced on first fragment. Why? How to fix it?
onCreate will be called on orientation change and you add the first fragment there. You can save which fragment you want to show in onSaveInstanceState and then use the instance state in onCreate to add the correct fragment.
EDIT:
You need to maintain a variable currentFragmentIndex and save it in onSaveInstanceState like so:
protected void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putInt("currentFragment", currentFragment);
}
Then retrieve it in onCreate and initialize the fragment accordingly:
public void onCreate(Bundle bundle) {
if (bundle!= null){
currentFragmentIndex= bundle.getInt("currentFragment");
} else {
currentFragmentIndex = 0;
}
switch(currentFragmentIndex) {
case 0:
// TODO: Add first fragment
break;
case 1:
// TODO: Add second fragment
break;
}
}
Don't forget to change currentFragmentIndex to 1 when you switch to the second fragment.
I ran into the same issue, though as a note, I'm using the v4 support library. After reading Sapan Diwakar's answer, I wondered if this was necessary; instead, I tried this...
if (null == mFragmentManager.findFragmentByTag(TAG_HERE)) {
mFragmentManager.beginTransaction()./*blah blah blah*/.commit();
}
...so the original fragment is only instantiated/attached if there's nothing already attached where it's supposed to go.
I've tested this a bit and it seems to be fine... of course, the fact that it works doesn't mean it's a good idea, but I'm too new at this to know why it wouldn't be. If anyone can chime in on that, it'd be useful.
Thanks for posting this question, and also to everyone with input!

Categories

Resources