I have a fragment containing a RecyclerView and a button. The fragment is brought up on pressing a button (which adds some data) in a previous fragment, and the recycler shows correctly populated, the button works. Then I go back to the previous fragmen, press the button again (adding more data) and the same piece of code brings up the same fragment, but the RecyclerView is unpopulated and the button doesn't work. From reading this question my guess is that I am doing something in my Fragment management - because as soon as I change orientation and the Fragment is recreated, the list shows fine and the button works fine.
So here is the management I'm doing on the fragments - I took it from an example on the internet, but I'm worried it's not correct
First there is a Base class which I make for my fragments:
public class BaseFragment extends Fragment {
private AbstractFragmentCallback mCallback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (AbstractFragmentCallback) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement " +
AbstractFragmentCallback.class.getCanonicalName());
}
}
/**
* This method replaces the currently shown fragment with a new
fragment of a particular class.
* If a fragment of the required class already shown - does
nothing.
* #param clazz the class of the fragment to show
* #param addToBackStack whether the replacement should be added
to back-stack
* #param args arguments for the newly created fragment (can be
null)
*/
public void replaceFragment(Class<? extends Fragment> clazz,
boolean addToBackStack,
Bundle args) {
mCallback.replaceFragment(clazz, addToBackStack, args);
}
public interface AbstractFragmentCallback {
/**
* Call to this method replaces the currently shown fragment
with a new one
*
* #param clazz the class of the new fragment
* #param addToBackStack whether the old fragment should be
added to the back stack
* #param args arguments to be set for the new fragment
*/
void replaceFragment(Class<? extends Fragment> clazz, boolean addToBackStack,
Bundle args);
}
}
So then my MainActivity implements the BaseFragment.AbstractfragmentCallback so:
public class MainActivity extends AppCompatActivity implements BaseFragment.AbstractFragmentCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(....);
if (null == savedInstanceState) {
replaceFragment(WelcomeFragment.class, false, null);
}
}
// ---------------------------------------------------------------------------------------------
//
// Fragments management
#Override
public void replaceFragment(Class<? extends Fragment> clazz, boolean addToBackStack,
Bundle args) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment newFragment;
try {
// Create new fragment
newFragment = clazz.newInstance();
if (args != null) newFragment.setArguments(args);
} catch (InstantiationException e) {
e.printStackTrace();
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
}
if (addToBackStack) {
ft.addToBackStack(null);
}
// Change to a new fragment
ft.replace(R.id.container, newFragment, clazz.getName());
ft.commit();
}
// End of fragments management
//
// ---------------------------------------------------------------------------------------------
}
and when my fragment with the button wants to bring up the list fragment it calls
replaceFragment(ListFragment.class, true, null);
So - to be clear, the ListFragemnt comes up, and all its code fires including recrersating the RecyclerView and repopulating it - I even see all the code in the adapter being called for each item - but the items do not appear in the list
public class ListFragment extends BaseFragment implements ListFragmentMvc.ListViewMvcListener {
private List<MyStuff> stuffList;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstance) {
stuffList = new ArrayList<>();
return inflater.inflate(R.layout.list_activity, container, true);
}
#Override
public void onResume() {
super.onResume();
recyclerView = mRootView.findViewById(R.id.recycler_view);
letsGoButton = mRootView.findViewById(R.id.lets_go_button);
letsGoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Activity activity = getActivity();
if (activity != null) {
getActivity().onBackPressed();
}
}
});
recyclerView.setItemAnimator(new DefaultItemAnimator());
DividerItemDecoration itemDecor = new DividerItemDecoration(context, HORIZONTAL);
recyclerView.addItemDecoration(itemDecor);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(mLayoutManager);
setData(MyApplication.getAllStuffItems());
}
public void setData(List<MyStuff> stuff) {
stuffList = stuff;
mAdapter = new StuffAdapter(stuffList);
recyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
}
So, anyone have a clue why this doesn't work until I change orientation on re-entering the listFragment?
Thanks
Can you try to move the code which sets/updates the recyclerView and letsGoButton from the onResume method to onViewCreated method as below:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView = view.findViewById(R.id.recycler_view);
letsGoButton = view.findViewById(R.id.lets_go_button);
letsGoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Activity activity = getActivity();
if (activity != null) {
getActivity().onBackPressed();
}
}
});
recyclerView.setItemAnimator(new DefaultItemAnimator());
DividerItemDecoration itemDecor = new DividerItemDecoration(context, HORIZONTAL);
recyclerView.addItemDecoration(itemDecor);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(mLayoutManager);
setData(MyApplication.getAllStuffItems());
}
Wow, that was a wild waste of a day.
In the end I had a couple of errors which were pasting over and hiding each other.
The real real reason this wasn't working, I think was because I should have had
return inflater.inflate(R.layout.list_activity, container, false);
instead of
return inflater.inflate(R.layout.list_activity, container, true);
I lied a little in my code because I wasn't really directly returning the result of inflater.inflate... I was calling it (with the wrong parameter) and then returning null.
I guess that will teach me to be more honest in the posting
I implemented AppCompatActivity that i used for fragment transaction. Only one AppCompatActivity like:
public class UIActivity extends AppCompatActivity {
...
}
The fragment can begin another transaction, leading to having more than one fragment of the same class in the back stack. (illustration)
public class UiFragment extends Fragment implements FileChooserListener {
mybutton.setOnclickListener(){
// do some stuff, met some condition and add fragment ( of UiFragment), possibly inflating another view, add previous fragment to back stack
}
}
This works fine except that even when i implemented onSaveInstance,on restore instance inflate the firstfragment while other are lost. I want to resume from where the user stopped and being able to access fragment in back stack when the user press the back button.
IMPLEMENTATION
in UIActivity
UIFragment uif;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.push_up_in, R.anim.push_up_out);
setContentView(R.layout.activity_ui);
if (savedInstanceState == null) {
uif = new UIFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("step", getIntent().getExtras().getSerializable("step"));
bundle.putString(UIFragment.STEP_KEY, getIntent().getExtras().getString(UIFragment.STEP_KEY));
uif.setArguments(bundle);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.content_frame, uif, "myfragment").commitAllowingStateLoss();
}
}
public void onSaveInstanceState(Bundle outState){
getSupportFragmentManager().putFragment(outState,"myfragment",uif);
}
public void onRestoreInstanceState(Bundle inState){
uif = (UIFragment)getSupportFragmentManager().findFragmentByTag("myfragment");
}
snippet that adds UIFragment to the stack
public void addNewUIFragment(){
UIFragment uif= new UIFragment ();
Bundle bundle = new Bundle();
bundle.putSerializable("step", step);
bundle.putString(UIFragment.STEP_KEY, sData);
uif.setArguments(bundle);
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.addToBackStack(null);
transaction.setCustomAnimations(R.anim.slide_in, R.anim.slide_out, R.anim.back_slide_in,
R.anim.back_slide_out);
transaction.add(R.id.content_frame, uif, "myfragment").commitAllowingStateLoss();
}
how to Saving and Restoring Fragment state in Android ?
my code for save and restore state :
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("CurrentState",CurrentState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
if (savedInstanceState != null) {
// Restore last state for checked position.
CurrentState = savedInstanceState.getInt("CurrentState", 0);
}
.
.
.
switch (CurrentState){
case 1 :button_DisplayMemoris.performClick();break;
case 2 :
linearLayout_AddMemoris.setVisibility(View.VISIBLE);
linearLayout_Memoris.setVisibility(View.GONE);
linearLayout_DisplayMemoris.setVisibility(View.GONE);
break;
default:break;
}
return inflate;
}
when CurrentState=2 , linearLayout_AddMemoris Not displayed
How do I fix it?
update :
this is my activity :
public class ToolsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tools);
displayView();
}
public void displayView() {
// update the main content by replacing fragments
Fragment fragment = = new MemoirsFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame_container, fragment);
ft.commit();
}
}
Is there a way to solve the problem?
I have no idea
Add in onCreate method null checking, now you are replace restored fragment by new fragment
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tools);
if (savedInstanceState == null)
displayView();
}
I have an Activity in which I go through several fragments. In every fragment I have several views (EditText, ListView, Map, etc).
How can I save the instance of the fragment that is shown at that moment? I need it to work when the activity is onPause() --> onResume(). Also I need it to work when I return from another fragment (pop from backstack).
From the main Activity I call the first fragment, then from the the fragment I call the next one.
Code for my Activity:
public class Activity_Main extends FragmentActivity{
public static Fragment_1 fragment_1;
public static Fragment_2 fragment_2;
public static Fragment_3 fragment_3;
public static FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fragment_1 = new Fragment_1();
fragment_2 = new Fragment_2();
fragment_3 = new Fragment_3();
fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction_1 = fragmentManager.beginTransaction();
transaction_1.replace(R.id.content_frame, fragment_1);
transaction_1.commit();
}}
Then here is the code for one of my fragments:
public class Fragment_1 extends Fragment {
private EditText title;
private Button go_next;
#Override
public View onCreateView(final LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_1,
container, false);
title = (EditText) rootView.findViewById(R.id.title);
go_next = (Button) rootView.findViewById(R.id.go_next);
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction transaction_2 = Activity_Main.fragmentManager
.beginTransaction();
transaction_2.replace(R.id.content_frame,
Activity_Main.fragment_2);
transaction_2.addToBackStack(null);
transaction_2.commit();
});
}}
I have searched a lot of information but nothing clear. Can somebody give a clear solution and an example, please ?
When a fragment is moved to the backstack, it isn't destroyed. All the instance variables remain there. So this is the place to save your data. In onActivityCreated you check the following conditions:
Is the bundle != null? If yes, that's where the data is saved (probably orientation change).
Is there data saved in instance variables? If yes, restore your state from them (or maybe do nothing, because everything is as it should be).
Otherwise your fragment is shown for the first time, create everything anew.
Edit: Here's an example
public class ExampleFragment extends Fragment {
private List<String> myData;
#Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("list", (Serializable) myData);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
//probably orientation change
myData = (List<String>) savedInstanceState.getSerializable("list");
} else {
if (myData != null) {
//returning from backstack, data is fine, do nothing
} else {
//newly created, compute data
myData = computeData();
}
}
}
}
Android fragment has some advantages and some disadvantages.
The most disadvantage of the fragment is that when you want to use a fragment you create it ones.
When you use it, onCreateView of the fragment is called for each time. If you want to keep state of the components in the fragment you must save fragment state and yout must load its state in the next shown.
This make fragment view a bit slow and weird.
I have found a solution and I have used this solution: "Everything is great. Every body can try".
When first time onCreateView is being run, create view as a global variable. When second time you call this fragment onCreateView is called again you can return this global view. The fragment component state will be kept.
View view;
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
setActionBar(null);
if (view != null) {
if ((ViewGroup)view.getParent() != null)
((ViewGroup)view.getParent()).removeView(view);
return view;
}
view = inflater.inflate(R.layout.mylayout, container, false);
}
Try this :
#Override
protected void onPause() {
super.onPause();
if (getSupportFragmentManager().findFragmentByTag("MyFragment") != null)
getSupportFragmentManager().findFragmentByTag("MyFragment").setRetainInstance(true);
}
#Override
protected void onResume() {
super.onResume();
if (getSupportFragmentManager().findFragmentByTag("MyFragment") != null)
getSupportFragmentManager().findFragmentByTag("MyFragment").getRetainInstance();
}
Hope this will help.
Also you can write this to activity tag in menifest file :
android:configChanges="orientation|screenSize"
Good luck !!!
In order to save the Fragment state you need to implement onSaveInstanceState():
"Also like an activity, you can retain the state of a fragment using a Bundle, in case the activity's process is killed and you need to restore the fragment state when the activity is recreated. You can save the state during the fragment's onSaveInstanceState() callback and restore it during either onCreate(), onCreateView(), or onActivityCreated(). For more information about saving state, see the Activities document."
http://developer.android.com/guide/components/fragments.html#Lifecycle
As stated here: Why use Fragment#setRetainInstance(boolean)?
you can also use fragments method setRetainInstance(true) like this:
public class MyFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// keep the fragment and all its data across screen rotation
setRetainInstance(true);
}
}
You can get current Fragment from fragmentManager. And if there are non of them in fragment manager you can create Fragment_1
public class MainActivity extends FragmentActivity {
public static Fragment_1 fragment_1;
public static Fragment_2 fragment_2;
public static Fragment_3 fragment_3;
public static FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.main);
fragment_1 = (Fragment_1) fragmentManager.findFragmentByTag("fragment1");
fragment_2 =(Fragment_2) fragmentManager.findFragmentByTag("fragment2");
fragment_3 = (Fragment_3) fragmentManager.findFragmentByTag("fragment3");
if(fragment_1==null && fragment_2==null && fragment_3==null){
fragment_1 = new Fragment_1();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment_1, "fragment1").commit();
}
}
}
also you can use setRetainInstance to true what it will do it ignore onDestroy() method in fragment and your application going to back ground and os kill your application to allocate more memory you will need to save all data you need in onSaveInstanceState bundle
public class Fragment_1 extends Fragment {
private EditText title;
private Button go_next;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true); //Will ignore onDestroy Method (Nested Fragments no need this if parent have it)
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
onRestoreInstanceStae(savedInstanceState);
return super.onCreateView(inflater, container, savedInstanceState);
}
//Here you can restore saved data in onSaveInstanceState Bundle
private void onRestoreInstanceState(Bundle savedInstanceState){
if(savedInstanceState!=null){
String SomeText = savedInstanceState.getString("title");
}
}
//Here you Save your data
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("title", "Some Text");
}
}
I'm not quite sure if this question is still bothering you, since it has been several months. But I would like to share how I dealt with this.
Here is the source code:
int FLAG = 0;
private View rootView;
private LinearLayout parentView;
/**
* The fragment argument representing the section number for this fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section number.
*/
public static Fragment2 newInstance(Bundle bundle) {
Fragment2 fragment = new Fragment2();
Bundle args = bundle;
fragment.setArguments(args);
return fragment;
}
public Fragment2() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Log.e("onCreateView","onCreateView");
if(FLAG!=12321){
rootView = inflater.inflate(R.layout.fragment_create_new_album, container, false);
changeFLAG(12321);
}
parentView=new LinearLayout(getActivity());
parentView.addView(rootView);
return parentView;
}
/* (non-Javadoc)
* #see android.support.v4.app.Fragment#onDestroy()
*/
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.e("onDestroy","onDestroy");
}
/* (non-Javadoc)
* #see android.support.v4.app.Fragment#onStart()
*/
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.e("onstart","onstart");
}
/* (non-Javadoc)
* #see android.support.v4.app.Fragment#onStop()
*/
#Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
if(false){
Bundle savedInstance=getArguments();
LinearLayout viewParent;
viewParent= (LinearLayout) rootView.getParent();
viewParent.removeView(rootView);
}
parentView.removeView(rootView);
Log.e("onStop","onstop");
}
#Override
public void onPause() {
super.onPause();
Log.e("onpause","onpause");
}
#Override
public void onResume() {
super.onResume();
Log.e("onResume","onResume");
}
And here is the MainActivity:
/**
* Fragment managing the behaviors, interactions and presentation of the
* navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in
* {#link #restoreActionBar()}.
*/
public static boolean fragment2InstanceExists=false;
public static Fragment2 fragment2=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager()
.findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
switch(position){
case 0:
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.container, Fragment1.newInstance(position+1)).commit();
break;
case 1:
Bundle bundle=new Bundle();
bundle.putInt("source_of_create",CommonMethods.CREATE_FROM_ACTIVITY);
if(!fragment2InstanceExists){
fragment2=Fragment2.newInstance(bundle);
fragment2InstanceExists=true;
}
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.container, fragment2).commit();
break;
case 2:
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.container, FolderExplorerFragment.newInstance(position+1)).commit();
break;
default:
break;
}
}
The parentView is the keypoint.
Normally, when onCreateView, we just use return rootView. But now, I add rootView to parentView, and then return parentView. To prevent "The specified child already has a parent. You must call removeView() on the ..." error, we need to call parentView.removeView(rootView), or the method I supplied is useless.
I also would like to share how I found it. Firstly, I set up a boolean to indicate if the instance exists. When the instance exists, the rootView will not be inflated again. But then, logcat gave the child already has a parent thing, so I decided to use another parent as a intermediate Parent View. That's how it works.
Hope it's helpful to you.
If you using bottombar and insted of viewpager you want to set custom fragment replacement logic with retrieve previously save state you can do using below code
String current_frag_tag = null;
String prev_frag_tag = null;
#Override
public void onTabSelected(TabLayout.Tab tab) {
switch (tab.getPosition()) {
case 0:
replaceFragment(new Fragment1(), "Fragment1");
break;
case 1:
replaceFragment(new Fragment2(), "Fragment2");
break;
case 2:
replaceFragment(new Fragment3(), "Fragment3");
break;
case 3:
replaceFragment(new Fragment4(), "Fragment4");
break;
default:
replaceFragment(new Fragment1(), "Fragment1");
break;
}
public void replaceFragment(Fragment fragment, String tag) {
if (current_frag_tag != null) {
prev_frag_tag = current_frag_tag;
}
current_frag_tag = tag;
FragmentManager manager = null;
try {
manager = requireActivity().getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (manager.findFragmentByTag(current_frag_tag) == null) { // No fragment in backStack with same tag..
ft.add(R.id.viewpagerLayout, fragment, current_frag_tag);
if (prev_frag_tag != null) {
try {
ft.hide(Objects.requireNonNull(manager.findFragmentByTag(prev_frag_tag)));
} catch (NullPointerException e) {
e.printStackTrace();
}
}
// ft.show(manager.findFragmentByTag(current_frag_tag));
ft.addToBackStack(current_frag_tag);
ft.commit();
} else {
try {
ft.hide(Objects.requireNonNull(manager.findFragmentByTag(prev_frag_tag)))
.show(Objects.requireNonNull(manager.findFragmentByTag(current_frag_tag))).commit();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Inside Child Fragments you can access fragment is visible or not using below method
note: you have to implement below method in child fragment
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
try {
if(hidden){
adapter.getFragment(mainVideoBinding.viewPagerVideoMain.getCurrentItem()).onPause();
}else{
adapter.getFragment(mainVideoBinding.viewPagerVideoMain.getCurrentItem()).onResume();
}
}catch (Exception e){
}
}
Below is my code:
public class MyListFragmentActivity extends FragmentActivity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("DEBUG : MLFA onCreate");
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(fragmentID, new MyListFragment())
.replace(detailFragmentID, new MyDetailFragment()).commit();
}
}
#Override
protected void onRestart() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment prevFrag = getSupportFragmentManager().findFragmentById(detailFragmentID);
if (prevFrag != null) {
fragmentTransaction.remove(prevFrag);
getSupportFragmentManager().beginTransaction().replace(detailFragmentID, new MyDetailFragment()).commitAllowingStateLoss();
} else {
getSupportFragmentManager().beginTransaction().replace(detailFragmentID, new MyDetailFragment()).commitAllowingStateLoss();
}
}
MyListFragment
public class MyListFragment extends Fragment{
//When we click on each item in list view call detail fragment to relad its layout
OnItemClickListener onItemClickListener = new OnItemClickListener() {
/** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
/** Getting the existing detailed fragment object, if it already exists.
* The fragment object is retrieved by its tag name
* */
Fragment prevFrag = getFragmentManager().findFragmentById(detailFragmentID);
/** Remove the existing detailed fragment object if it exists */
if (prevFrag != null) {
fragmentTransaction.remove(prevFrag);
MyDetailFragment mydetailFragment = new MyDetailFragment();
fragmentTransaction.replace(detailFragmentID, mydetailFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.show(getFragmentManager().findFragmentById(detailFragmentID));
fragmentTransaction.commit();
}
}
MyDetailFragment
public class MyDetailFragment extends Fragment{
onCreate() // on create being called multiple times ? why ?????????????
onCreateView()
}
When i click on my list item MyDetailFragment onCreate() is called only once, but when i tilt the device to portrait or landscape then MyDetailFragment onCreate() is called multiple times ?
Why so? What am i doing wrong here and how to fix this ?
Every time you change the orientation, it is as good as restarting the app. You need to handle changes appropriately like releasing the resources, acquiring them again, stopping any work you were doing and resuming them and so on.
You aren't doing anything wrong.