How to restore dynamic views to the android app? - android

I am creating dynamic views, Adding them to the layout those views are adding fine.But once i close the app and open it Dynamic views are not visible,I want to display those views after opening the app second time. Will you give me any idea, Thanks in advance.

You'll have to manually add the view's state to the saved instance state bundle, and recreate it from there.
This is accomplished by overriding onSaveInstanceState() on your Activity and/or View. The state will be later available in the creation Bundle (onCreate(bundle)). You can use that data to re-instantiate your views.
The correct OOP way of things would be to create a class for your dynamically created view that implements a custom onSaveInstanceState() method, and then packing it and unpacking it into the Activity's bundle.
This blog post contains details and examples on how to tackle the issue. Some more related info in this other SO question

Related

What are the advantages of adding a fragment via XML vs programmatically?

From the Android documentation it's not very clear to me which are the advantages and practical use cases of adding fragments via XML compared to adding them programmatically.
Do both methods allow sending data from the activity to the fragment and back using Bundle?
Can both methods behave similarly in the activity lifecycle?
Some short examples or references will surely help.
Both the methods have only slight difference. If you add fragment in XML, then you are first loading or creating it then you will get its instance and vice-versa for the other approach.
Also, programmatically adding fragment gives you advantage of changing its attributes dynamically whereas you have fixed values if you add it from XML.
Not that much major difference it has.
With FragmentContainerView and using the android:name or android:class, you can avoid the boiler plate code of instantiating the fragment only when savedInstanceState is null or when it is not already added.
If you do that programmatically, you need to make sure that you only add the fragment if it is not already added to the activity by checking:
if (getSupportFragmentManager().findFragmentByTag(CUSTOM_TAG) != null)
{
// You can also easily add animations or pass custom data.
getSupportFragmentManager().beginTransaction().add(R.id.container_view, YourFragment.newInstance(data), CUSTOM_TAG).commit();
}
Programmatically doing it gives you advantages of passing custom data, adding it when you actually need it. In case of layout method, it will be instantiated when the activity's layout gets inflated. But many times, we don't need to add a fragment immediately, adding it programmatically would be a better option in that case.
No difference at all. Android has a system for instantiating objects from XML, but it's always interchangeable with actually executing constructors and the methods to add children. The difference is convenience: The XML system allows you to easily link other resources and it has features to help with passing the right parameters.

Fragment view state not saved on back press when using Android Jetpack Navigation

In my app I'm using the Jetpack navigation component and I have an issue with fragment state not being saved when navigating back to a fragment.
When I navigate from MainFragment to SettingsFragment it's via the overflow menu:
NavigationUI.onNavDestinationSelected(item, Navigation.findNavController(view));
When navigating back to MainFragment, the visibility on some views and text in some TextViews is not saved, and my state machine variable has lost its state as well.
I've read solutions where the root view is saved in a global variable in the fragment, and while this solves the visibility issue on views, the TextViews are still empty and the state machine variable is reset.
Is there a proper way to make sure fragment state is saved in this case?
If you're using view model then it can save state for you. However, that only works for simple views. For complex views including some custom views that you created, make sure that you have assigned a unique id to those as Android uses those ids to recover their state. You can use generateViewId() method on View to do so. Worst case, you might need to implement onSavedInstanceState and onRestoreInstanceState on your views.
Also, make sure you have not set to setRetainInstance to false in the xml or code.
While doing that please make sure you use parcelize annotation for your parcelable data models as this can save you a lot of time.
I hope your problem is solved by assigning unique IDs and you don't have to deal with saving state. Good luck!

ViewPager Fragment Views retaining values from previous state

I have a 3-tab ViewPager with custom Fragments (EntryFragment and CalendarFragment; the third is not relevant to the question). Now when I click a date on CalendarFragment the EntryFragment should load up with data of the new date (I have coded it this way).
Now, what happens is something strange: The TextFields in EntryFragment get changed to the new data from the new date. But the Seekbars, Spinners, Switches, etc retain data from their previous date.
I am using the following methods to set the values of the various Views:
seekbar.setProgress(int);
spinner.setSelection(int, false);
switch.setChecked(boolean);
Also, I have attached onItemSelectedListerners for these components. These are getting called automatically after onCreateView() of EntryFragment.
Could anyone guide me why this is happening? Or how to prevent it?
I'm guessing it might be restoring previous state, ViewPagers have inbuilt mechanism to restore views that had been hidden. Your data is set to correct values and restored to previous state after that. To prevent that, try to add saveEnabled=false in xml layout of views you are having problem with.

android saving state of many layouts

I have a simple chat app where a RelativeLayout with multiple views is created for each message. After the activity is stopped or destroyed all of my added layouts disappear from the parent so all messages are gone.
Sure I could put the ID (along with other values) of each single view into a SharedPreferences object or a database to restore all messages after the activity is re-created.. but is there a simpler way to save the dynamically created layouts..? The parent is defined by XML.
When an Activity (or a Fragment) becomes invisible - its View hierarchy gets destroyed, and you can't overcome that. In fact, you don't need too. The solution is to store the messages inside a database and recreate the View hierarchy on Activity startup based on the database contents. No need to reinvent the wheel here. Hope this helps.
Put your Collection of messages in the Bundle savedInstanceState at OnSaveInstanceState() and restore them in your onCreate() from that.

Android TabActivity and dynamic Tabs screen orientation issue

I am adding Views (not Activities) to a TabActivity on demand (meaning that the activity can have zero or more tabs after onCreate is done). Over the time more tabs get added, now I need to save them in a sane way so I can restore them later on. I tried to use saveHierarchyState etc on the individual views, but they are restored without data from the editTexts etc.
So given that I have a HashMap in the activity which maps from tabkeys to views, how would you save this data and restore it?
Okay, I got it :)
First I thought I needed to set the IDs of the Views as described here -- using this approach Android is able to restore the view states. But since my dynamic tabs all use views from the same layout their children all have the same IDs, so android will overwrite the data (The state is saved in a sparse array according to the view ID, so the IDs should be unique) and all views look the same. I fixed that by manually saving the state of my views and reapplying it via:
SparseArray<Parcelable> container = new SparseArray<Parcelable>();
saveHierarchyState(container);
b.putSparseParcelableArray("state", container);
restoreHierarchyState(b.getSparseParcelableArray("state"));
While this approach works I still have to find out if I can let Android do all the work by not setting IDs for the Views in the layout xml file (if that's allowed/possible).

Categories

Resources