Although i saw many issues on this an tried to implement all of them i decided to ask this question again since none of the suggested methods worked for me.
Problem:
Im trying to show a custom dialog based on a DialogFragment inside an ActivityFragment.
the Activity is being recreated on orientation change since it has a different layout.
Every time that happens the DialogFragment vanishes. (i am using the latest support package)
Things i have tired:
using the onRetainCustomNonConfigurationInstance to try and save the dilaog.
Use setRetainInstance (true) in the dialog onCreate.
a static newInstance() method in the dialog.
override the dialog onDestroy to remove the destroy listener on the inner dialog
and some other documented solutions.
nothing seems to work, i tired with may variations of these solutions, the reason my custom dialog holds many ui elements in various states and i really have to get this to work.
If anyone could please provide some code to a solution it would be much appreciated.
Thanks,
Totem
The problem was that the FragmentManager is also retained through the onSaveInstanceState() of the parent which i neglected to call when overriding it in the ActivityFragment for my own purposes.
Thanks,
Totem
Related
Good day,
I'm working on an application that will serve as a monitor of some sort for drivers. My client would like the application to work regardless of the orientation of the device.
I implemented the solution provided in the following article , and after fiddling a bit with the debugger, I can see that the Asynctask is still working. However, the TextViews and ImageViews it is supposed to work on are not working anymore.
Here is the code of my TaskFragment.
To clarify : The AsyncTask still receive and handle the elements correctly, but the elements of the layout are not updated anymore. I would like to know how I can keep them working.
I would suggest using an AsyncTaskLoader as those can re-attach to whatever lifecycle element you created it in relatively easily. See here: https://developer.android.com/reference/android/content/AsyncTaskLoader.html
It might seem pretty involved to implement at first, however if you read https://developer.android.com/guide/components/loaders.html, most of the weirdness should be cleared up.
TLDR: Using AsyncTaskLoader allows an easy way for your AsyncTask to be reattached to your fragment after it is destroyed and recreated. You just need to call getLoaderManager().initLoader(...) in the onCreate of your fragment.
Ok, so I found a (probably not very efficient) workaround, but a workaround nonetheless.
The problem was that, after an orientation change, since the Activity is destroyed and recreated, the variables batterymonitor, valuemonitor, etc, would not point towards the new objects created because of the layout/activity change.
As a solution, I am now using a findViewById each time I need to do an operation on the layout. This way, the id is permanently refreshed to keep up with the activity changes on a rotation of the device.
The ugly line I use to do so is :
batteryMonitor = (ImageView)getActivity().findViewById(R.id.batteryMonitor);
batteryMonitor.setImageResource(R.drawable.no_battery);
I have searched many post on stackoverflow but didn't get the reason behind this.
If you look at the documentation (link), this function is used by the system to prioritize; therefore you want the system to know which priority has this fragment before you ask the system to create the view.
I'll get straight to the point. Dialog's confuse the hell out of me. Why? Because it seems as though there are 5 different ways on instantiating them, giving them a custom layout, and using them. To add insult to injury the documentation on them is very poor. so I'm going to post the main questions I have here, and hope you guys can clear some of the confusion for me.
Question One:
what is the Real Difference between Dialog, and DialogFragment?
Question Two:
why is it better to use onCreateView, rather than onCreateDialog?
furthermore, Whats the difference?
Question Three:
why not just do *Dialog dialog = new Dialog();* everytime i need one,
rather than subclass DialogFragment constantly?
I apologize if this thread may not seem like a good fit for the community, but please keep in mind these are very real, and un-answered questions. Of all the tutorials I've read, from slidenerd-to-vogella-to-Stack everything explains the How, but not Why, which is just as important, if not more. Thanks Guys!
The difference between them is that a Dialog can only show a custom view but has no means in itself for you to interact with it's views / widgets programmatically at the runtime of the Dialog (ie when it's shown). DialogFragment extends Fragment and has all capabilities and the lifecycle of a Fragment (or very similar to them when used as a dialog).
DialogFragment can also be used as a 'normal' fragment, which means you could use a DialogFragment to show a dialog on a tablet or have it live inside an activity (ie full-screen) on a phone.
If the DialogFragment is also to be used as a Fragment, it has to return a View via onCreateView, so you'll have to implement onCreateView anyway. You can probably avoid code repetition if you only implement onCreateView and not onCreateView and onCreateDialog. But I've never heard someone say that is is 'better to use onCreateView, rather than onCreateDialog'.
You don't have to subclass DialogFragment for most dialogs. To show a simple Dialog eg. asking the user a question of showing a little bit of information, you can instantiate a new Dialog() or use the DialogBuilder. I use DialogFragments only when there's some logic going on within the Dialog that I want to reside in it's own class and makes use of the DialogFragments lifecycle.
I am developing an Android library to ask the users of an app to give a rating on the Play Store.
The UX of the library consists in a few dialogs. Depending on the answer to the first question I might need to dismiss the current dialog, to show another dialog or to take the user to the Play Store.
Everything works nice unless I rotate the screen in the middle of the process.
I tried to solve my issues with the use of fragments. With fragments I am not losing anymore the state of the dialogs with the rotation but I am having troubles instantiating the second DialogFragment. The problem is that, after a rotation, the context of the first DialogFragment is no more active and it has no way to retrieve the new context. That results in exceptions every time I try to instantiate the new DialogFragment.
Is there any way I could solve this issue?
Thinking again at the problem, it seems that my design choice was wrong but I am not very experienced in Android development. Every advice will be more than welcome.
You should be using the listener pattern. Define an interface in each dialog and send clicks back to the activity. Let it create the dialogs.
see here
Also, if you need a context in the fragments, just call getActivity(), don't create an unnecessary context variable that could later give back an activity that's already gone. I hope that helps. I can't give a better answer without some code to see what's going wrong in this specific situation.
I was using ActionBarSherlock and ViewPager to have 4 fragments as the tab pages in a SherlockFragmentActivity.
In normal conditions, this solution worked fine.
However, if the application exited abnormally, i.e., killed by the Android OS because of memory shortage, the ViewPager was unable to attach the newly created fragments to the activity any more when navigating back to the SherlockFragmentActivity.
With lots of debugging, I finally found out that SherlockFragmentActivity 'remembered' the fragments attached to it. When it was re-created, it would re-create and attach the fragments to itself, that prevented ViewPager from attaching any new fragment to the activity.
I worked around this issue by overwrite SherlockFragmentActivity#onSaveInstanceState with an empty implementation to force SherlockFragmentActivity to forget all the fragments. But I still have not any perfect solution.
I suspected this is a defect of SherlockFragmentActivity.
As a summary, I think SherlockFragmentActivity has a defect of restoring inner fragments when working with ViewPager.
Did anybody encounter the same issue?
Based on what you have said, I see little evidence of a bug here. Your solution is a good one which is widely used.
However I do want to question your analysis. If the fragments are static (XML) then Android will recreate them automatically. However, if you are creating the fragments dynamically ( and I assume you are if you are using tabs) then the Android system will not recreate them automatically after the activity is destroyed. In this case you should use onSaveInstanceState to programmatically restore the fragment/tab.
Although you have not mentioned the issue of configuration changes , if you are using ABS, you should not attempt to handle the configuration change in your app. This is the only deviation from "standard" that I have encountered whilst using ABS.
If you are looking for high quality responses here then I suggest that you post code and a logcat trace.
I've encountered similar issue. Solution works for me:
At first, fragments are being re-created using default constructor. So if You passing some args in your custom constructor to fragments, You should save 'em duriong onSaveInstanceState and getting 'em out in onCreateView().
It will save your fragments if whole app is not killed by OS.
To restore fragments after whole app re-create, use SharedPrefs to save important data.
Good place to do it in onStop() method and restore in onCreateView().
If You need code sample let me know, but it seems it would not be a problem for You.