This confuses me a lot.
I had two fragments, and I use FragmentTransaction.replace() the swap the two fragments. State of some input controls like RadioGroup and checkbox is always preserved when I switch to the other fragments and switch back again.
.
I set break point on my OnCreateView() of Fragment, and every swap seems to trigger the method and new views are created each time. The savedInstanceBundle is always null as well. Since the new views are created, how do they get the state of the old views?
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_fieldsetup_marking, container, false);
// ...
return v;
}
This effect is fine for my app, but I just want to know how it is implemented.
where are the states stored?
Where is the android SDK code to restore this (I can not find any in the class FragmentTransection).
Related
I am absolutely in love with these new components Android is introducing. So, I am building a standard mobile application with solely one activity using the Navigation components and Architecture components such as a View Model as I am performing a lot of communication with my data that I stored in room.
In one of my bottom navigation tabs, I have a list that is loaded from all my data in room. So far, I have set up my RecyclerView and my adapter in the OnCreateView() (only function used in this fragment) of this list fragment and every thing shows successfully.
The problem is that every time (especially more at first view) the fragment takes a solid 10 seconds to display all the data (which is normal considering there is a lot of it).
My question: Is there a way the adapter and and RecylcerView of this specific fragment could be setup (and load all my data) in the OnCreate() of my sole activity? So that when I view the fragment for the first time, everything pops up right away.
Also, how would I go about using OnPause() of the list fragment so that when I am on another tab, the list fragment doesn't get destroyed and when we go back on it, it displays right away?
Fetch all data from room inside onCreate() method of fragment. The onDestroyView() method calls everytime you moves away from the fragment.
To prevent recreation of views inside fragment store view in a variable.
Example:
class YourFragment extends Fragment{
View rootView;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
//fetch data from room
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
if(rootView == null)
rootView = inflater.inflate(R.layout.your_fragment_layout, container, false);
return rootView;
}
}
In an Android Fragment, which is a part of a ViewPager, there is a ListView with EditText for filtering.
filterEditText = (EditText) view.findViewById(R.id.filter_friends);
filterEditText. addTextChangedListener(textWatcher);
When I navigate to another Fragment ondestroyview is called and then when I navigate back to this fragment onCreateView is called and the filtering doesn't work anymore, though the instance variables still exist.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_new_game_facebook, container,
false);
return view;
}
How this situation should be handled correctly?
You are probably using a FragmentStatePagerAdapter, which will destroy all non-active fragments to save memory. This is helpful for when you do not know how many fragments you will use until runtime, but is overly aggressive if you know which fragments will be in the pager. Try using a FragmentPagerAdapter instead, which will not destroy the fragments as soon as you navigate away from them, so you will not need to manually persist the state of each fragment and reload it.
Hey all, quick question..
Right now i have a fragmenttabhost with 4 tabs and by default tab 0 is loaded when the application is started up, this makes sense. However, i do not want to load any tabs until the specific tab is touched. Simply because tab0 does a decent amount of work that does not need to be done unless touched.
Ive though about passing a true/false to the bundle to show it or not:
mTabHost.addTab(createTab("tab1", "test1", R.drawable.ico1), TabClass1.class, false);
mTabHost.addTab(createTab("tab2", "test2", R.drawable.ico2), TabClass2.class, false);
mTabHost.addTab(createTab("tab3", "test3", R.drawable.ico3), TabClass3.class, false);
mTabHost.addTab(createTab("tab4", "test4", R.drawable.ico4), TabClass4.class, false);
So in the oncreateview would look something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getArguments();
//pseudo
if(true )return inflater.inflate(R.layout.tab_messages, container, false);
else return null;
}
but it seems like there should be an easier way to say "ok heres my tabs dont load them until touched"
I tried setting the curretTab to -1 but that didnt do anything.
Any help would be great!
Do your job in
setUserVisibleHint()
There can be some issues if it is called before onCreateView or you might want not to get those events until onResume is called.
Extend your tabs with this Fragment. It will call onVisible not earlier than onResume and will provide subsequent updates if setUserVisibleHint is called by the system.
UserVisibleHintFragment
And do your stuff in
onVisible()
Though I'm not sure that TabHost will call setUserVisibleHint (at least ViewPager does)
this is bit when i'm creating view,
public static int a=0;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
a++;
View view = inflater.inflate(R.layout.fragment_layout, container, false);
editText = (EditText) view.findViewById(R.id.amount);
TextView tv = (TextView) view.findViewById(R.id.textView1);
Button button = (Button) view.findViewById(R.id.addTransaction);
button.setOnClickListener(this); ///fragments implements OnClickListener
editText.setText(""+a);
tv.setText(""+a);
return view;
}
when i load this fragment first time, my editText is empty, but when i load fragment again, value in the editText is same like in previous execution.
Is anyone has idea what i'm doing wrong? And how i can fix it?
** EDIT
i modified little bit my code, now each time when i'm loading fragment a is incremented. and io noticed weird behaviour. tv has has actual value of a, while editText still has old value
You need to move the settext ( and probably some other stuff) into a later method in the fragment life cycle e.g. onActivityCreated.
Before adding the fragment try to get the fragment by calling FindFragmentByTag("tag"), i think you are adding new fragments on top of each other. Also add your fragment transaction to back state and then to check if more than one fragments are added, press back button. I had similar problem, and the reason was i kept adding new fragments in activity
Fragments are tied to activities, so my guess is that the activity is not being destroyed, which means your fragment is not being destroyed and instead "resumed". Perhaps you want that code in the onResume callback? Take a look at the Fragment lifecycle: Android Fragments
Im making an App. And I want to access my 3 main activities into 3 different fragments. i use viewpager to swap activities but it only show layouts do not work on its functionality. Then i used Fragment to use functions. but my problem is same its only show layouts not is functions.
i made 3 different fragment for 3 activities and use
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.settings, container, false);
return v;
}
method.
idont know how to use onActivityCreated() method or getActivity(). please help me..
i search all of it about it but cannot done yet.. :(
To access Widget Of layout just use this
View.findViewById();