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
Related
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).
I have an activity with a number of fragments. In all fragments, I get the views in onViewCreated, like this:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv1 = (TextView)view.findViewById(R.id.tv1);
tv2 = (TextView)view.findViewById(R.id.tv2);
tv3 = (TextView)view.findViewById(R.id.tv3);
}
I'm not storing the textview's text in the state. One fragment extends ListFragment and I change the adapter's items and refresh the listview.
When I go back to previous fragments (I use popBackStack() because I need to use a Back button (app runs in kiosk mode), text in some fragments is lost while in others (and the listview) the changes done stay there.
I'm using replace to replace the current fragment in the frame.
EDIT
The values that are being lost are of TextViews and ImageButtons (image resource). The text in EditText views are not lost.
Why is this happening in just some fragments and how can I solve this data loss?
You have to use
android:freezesText="true"
In your layout textviews whose text you want to be preserved.
I hope it helps.
Let me see if I understand your situation:
You are showing an instance of Fragment1 which contains your TextView.
You replace your instance of Fragment1 on the screen with an instance of Fragment2.
You return to Fragment1, but when you do, the text in the TextView has been lost.
I have seen situations where this occurs because the instance of Fragment1 that contained the original TextView is not the same instance of Fragment1 that is shown the second time. If you are showing two different instances of Fragment1, the second instance will not display the text that the first instance contained in its own text view.
So take a look at the code that is managing your fragment transactions. Are you creating new instances of your fragments before showing them? If so, you'll have to keep references to the fragments that you want to retain instead of recreating them every time.
Another thing to look at would be how the TextView is being populated. Maybe the actual data is being lost somewhere.
Use Instance variables to store data inside each Fragment, if you are using replace E.g.:
String value = "";
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv1 = (TextView)view.findViewById(R.id.tv1);
tv1.setText(value);
}
Note: Update value variable as well whenever textview data is being updated.
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.
As a preamble; I have an Android app containing 4 activities, and I wish to transfer these into a single activity containing Fragments (two extending ListActivity, and two extending Activity), with navigation between Fragments enabled by a Navigation Drawer . I have attempted to turn these Activities into ones extending ListFragment and Fragment, however much of the code within the activity ceases to function: for example, getSystemService(NOTIFICATION_SERVICE), the unbindService and the 'registerReciever', and primarily the different onCreateOptionsMenus contained within the disparate activities.
Therefore I ask, would it be possible to port any separate Activities to a single fragmented one, but still retaining the same function as with the separate focused activities, with minimal editing?
Also, regarding the transition process would one need to end a previous Fragment within the main Activity to display another Fragment in the same space?
Yes it is possible, fragments have a very similar lifecycle to activities (See here). You'll find it is probably a case of copy/paste from your activity classes to your fragment classes with very minor tweaks to have them work as they were as separate activities. The only legwork you will have to do is swapping these fragments from your activities.
For example, an activity with its onCreate function that looks like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// Find views
homeMessagesButton = (Button) v.findViewById(R.id.homeMessagesButton);
homeCreateMatchButton = (Button) v.findViewById(R.id.homeCreateMatchButton);
homeMyMatchesButton = (Button) v.findViewById(R.id.homeMyMatchesButton);
homeMyTeamsButton = (Button) v.findViewById(R.id.homeMyTeamsButton);
homeSquadButton = (Button) v.findViewById(R.id.homeSquadButton);
homeSettingsButton = (Button) v.findViewById(R.id.homeSettingsButton);
// Set click listeners
homeMessagesButton.setOnClickListener(this);
homeCreateMatchButton.setOnClickListener(this);
homeMyMatchesButton.setOnClickListener(this);
homeMyTeamsButton.setOnClickListener(this);
homeSquadButton.setOnClickListener(this);
homeSettingsButton.setOnClickListener(this);
}
Will now look like this in a fragment (note the fragment uses the onCreateView lifecycle method to inflate its view inside the activity the fragment will appear in)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_home, container, false);
// Find views
homeMessagesButton = (Button) v.findViewById(R.id.homeMessagesButton);
homeCreateMatchButton = (Button) v.findViewById(R.id.homeCreateMatchButton);
homeMyMatchesButton = (Button) v.findViewById(R.id.homeMyMatchesButton);
homeMyTeamsButton = (Button) v.findViewById(R.id.homeMyTeamsButton);
homeSquadButton = (Button) v.findViewById(R.id.homeSquadButton);
homeSettingsButton = (Button) v.findViewById(R.id.homeSettingsButton);
// Set click listeners
homeMessagesButton.setOnClickListener(this);
homeCreateMatchButton.setOnClickListener(this);
homeMyMatchesButton.setOnClickListener(this);
homeMyTeamsButton.setOnClickListener(this);
homeSquadButton.setOnClickListener(this);
homeSettingsButton.setOnClickListener(this);
return v;
}
Changing fragments within the activity is done through the use of the fragmentTransaction manager as shown in the android training site here
Since your service requires to be bound to a activity, rather than a fragment. This becomes trivial as fragments can retrieve the activity they are bound to. For example, the code below used in a fragment will automatically get the activity they exist within.
getActivity().getSystemService(Context.LOCATION_SERVICE);
If you want to use getSystemService(NOTIFICATION_SERVICE) in your fragments you need to use the context of your activity. Context.getSystemService(NOTIFICATION_SERVICE). Some methods work on Activities and if you want to use them elsewhere you need to get the context.
Moving your code from Activity is fairly simple. For example onCreateOptionsMenu is also available in Fragments and as for your methods that require a context or Activity, you can call getActivity() from your Fragment to get a reference to the parent Activity.
EDIT : to replace a Fragment, there's also a method for that from the FragmentTransaction class, taking the id of the container View in argument.
this is a though one for me. I have a MainActiviy which extends FragmentAnctivity. There I have 1 FrameLayout and buttons below to change frame's content. I do so by switching show/hide for created fragments which I added to FrameLayout before in OnCreate.
I'm also nesting more fragments in 1 fragment (As I have 1 fragment for 1 type of content and inside of it there is listFragment which is changed to DetailFragment after OnItemClick... again with show/hide approach).
Problem is that in 2 different contents I have 2 different instances of 1 Fragment class, so those 2 instances use 1 same layout file. And although the first of those fragment is hidden and 2nd is shown, when I change some view through 2nd instance then layout of 1st instance is changed and 2nd remains same as before. (Hope it is understandable)
I guess it's totally a mistake in managing and understanding of fragments' lifecycle, so can please someone help me to solve this?
Thanks very much :)
I suppose you get main point of fragments using practices. Your problem is simple. I almost sure you use getActivity().findViewById(...) calls to access views in your Fragment (or nested Fragment whatever). I this case Activity would return you fist view with defined id from whole your views hierarchy.
Solution is pretty simple - you just must avoid getActivity().findViewById(...) construction and get all links to views in onCreateView() callback and use exact this link with all future operations. Than everything will be ok. Here is simple example:
private TextView mDummyText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.layout_name, container, false);
initMembersViews(v);
return v;
}
private void initMembersViews(View v) {
mDummyText = (TextView) v.findViewById(R.id.fr_houses_list_text);
}
Hope it would helps you! Good luck!