Fragment save the state of a listener - android

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.

Related

Load data to a list fragment tab on the creation of the MainActivity

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;
}
}

What does "State" mean in Android fragment

In android, we keeps talking about retain the activity state/fragment state, but I have this question, what does "state" mean indeed. For example, suppose I have the following DialogFragment
public class Dialog extends DialogFragment {
private String mMessage;
#Override
public void onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
((TextView) v.findViewById("message")).setText(mMessage);
}
}
But wouldn't "mMessage" be retained as a member variable during device rotation? So in this case, does "mMessage" considered a state that I have to retain and put into argument when creating this fragment?
On a device rotation, the currently visible Activity is destroyed. Some widgets such as DialogFragment save and restore their own state.
Handling Configuration
Activity Lifecycle
The concept of State comes from OOP, not from android, to simplify: an object has a state (the data) and a behavior (the code).
Fragments and Activities work a bit different, fragments will retain the state if they are stopped, but they will lose it of the activity that manages them is destroyed (unless you retain it). Activities, however, will lose the state upon change of configuration.
The doc explains the lifecycle and how/when to retain fragments:
https://developer.android.com/guide/components/fragments.html#Lifecycle

onCreate() is not overridden when extending Fragment

I have this code:
public class CrimeListFragment extends Fragment {
private RecyclerView mCrimeRecyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime_list, container, false);
mCrimeRecyclerView = (RecyclerView) view
.findViewById(R.id.crime_recycler_view);
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
}
I know that when creating fragment, you separately implement onCreate() and onCreateView(). However, onCreate() is obviously missing here.
Why is that?
you separately call onCreate() and onCreateView()
No, you don't call either. The Fragment lifecycle calls them.
onCreate is not needed to be implemented on a simple Fragment class, only Activity classes
As for the title of your question - it should be called if you add that Fragment to an Activity.
Both onCreate() and onCreateView() can be overridden by you.
onCreate() is more optional and you can use to instantiate some variables (but you hardly need to override it).
onCreateView() is mandatory since you must inflate the view that you want and return it (like return view;).
In the docs:
onCreate()
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
onCreateView()
The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.
You can also check the Fragment Life Cycle.
As you can see in picture below, in case of returning from back stack, only onCreateView() is called again... So, you can use onCreate() to run some code that can be executed only once (when Fragment is created... like configure some array or something like that)...
Then, you leave onCreateView() just to refresh/inflate the Views before displaying it to the user.
But again: onCreate() is not usually overriden and there's no problem with that... Is always up to you...
:

Android - How the state of views are preserved during Fragment Transforamtion

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).

Problems with views when reloading fragment

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

Categories

Resources