I'm attaching the fragment (many fragments to FrameLayout) of an Activity each fragment has its own view inflated in onCreateView().
Now,
If I rotate the screen Landscape/Protrait the onCreateView() of the fragment is called instead of calling its attached Activity's onCreate() method. Because of this the view are rendered twice.
I want the Activity's onCreate() to be called every time when there is a config changes. Is it possible?
Activity : MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
getSupportFragmentManager().beginTransaction()
.add(R.id.layout_replace, new MyFragment()).commit();
}
Fragment : MyFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return (ScrollView)inflater.inflate(R.layout.some_layout, container, false);
}
Fixed this!!
Actual problem was with FragmentTransaction for which I'm adding fragments using .add() which causes the view to be populated twice.
Instead use :
.replace(R.id.yourId, fragment)
Related
I am using fragments to design my screen.When I navigate back to another fragment (from the back stack), the onCreateView(...) method gets called each time even if the fragment has already been created.How to avoid that the method onCreateView(...) gets called each time and make sure it's called only once (when it's created the first time)?
You can cache your inflated view to the local field if your want. For example:
public class ExampleFragment extends Fragment {
private View fragmentView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
if (fragmentView == null) {
fragmentView = inflater.inflate(R.layout.you_super_view_id, container);
}
return fragmentView;
}
}
But practically, it's ok that pager is reinflating views because it keeps only part of all fragments in memory at the time. So, I think the best idea is to let it work as it should
This question already has answers here:
NullPointerException accessing views in onCreate()
(13 answers)
Closed 8 years ago.
EDIT
Changed title.
SDK Guide document says, Activity.onCreate complete after Fragment.onCreateView and Fragment.onAcvityCreated.
But If I try findViewById for a view of the fragment it returns null.
How can I access contents of the fragment?
I'm very new to Android UI dev.
Below is a sample code generated by Eclipse IDE.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
// this is null
View rootView = findViewById(R.id.txtView);
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
First of all, I want to access inner contents of the 'fragment_main'.
Can I do this with findViewById?
I found that calling findViewById for a view of the fragment at onCreate call is not working.
How do I know when the Fragment views are ready at the Activity level?
I read How to implement OnFragmentInteractionListener
Am I needed to manually implement a event listener for this?
I think short answer is 'impossible' or 'not works like that'.
If one want to manage inner contents of fragments just delete fragments and move all the contents to the activity layout.
But If I try findViewById for a view of the fragment it returns null.
You can not just access the view of the fragment in your activity's oncreate or where ever, you can call view of the fragment in your activity.
I found that calling findViewById for a view of the fragment at onCreate call is not working.
That is because the view is not inflated yet in your fragment thus returning null.
Have a look at the fragment life cycle:
(source: xamarin.com)
As you can see onCreate is before onCreateView which you inflate your view for the fragment's layout.
solution:
you call findViewByIdit in your fragment's onActivityCreated.
sample:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView sample = (TextView) getView().findViewById(your_id);
}
I have a fragment that seems to be automatically restoring state over a screen rotation configuration change. I can verify in the logs that onCreatView is called in the fragment whenever the screen is rotated. Despite calling down to applyDefaults(), the draft entries that the user made are retained when the screen rotates and onCreateView() is called.
My understanding is that I would have to save state in onSaveInstanceState() and restore it in onCreateView(), but that doesn't seem to be the case. Can someone explain?
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView()");
View view = inflater.inflate(R.layout.fragment_email_entry, container, false);
m_hostNameEditText = (EditText) view.findViewById(R.id.hostNameEditText);
// set reference for other fields
applyDefaultsForNewEmailAccount();
return view;
}
private void applyDefaults() {
m_hostNameEditText.setText("");
// set other defaults
}
It may have to do with the fact that my Activity inherits from SingleFragmentActivity, so perhaps it sees that the fragment is already in the view. Still, we know that Fragment.onCreateView() is being called.
public abstract class SingleFragmentActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_fragment_activity);
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.single_frame_container);
if (fragment == null) {
fragment = createFragment();
fragmentManager.beginTransaction()
.add(R.id.single_frame_container, fragment)
.commit();
}
}
public abstract Fragment createFragment();
}
Just like an activity, a fragment will automatically save the data of
any fragment View component in the Bundle by the View component’s id.
And just like in the activity, if you do implement the
onSaveInstanceState( ) method make sure you add calls to the
super.onSaveInstanceState( ) methods so as to retain this automatic
save of View data feature.
source
I am using several fragments to be dynamically added into activity. Everything works fine, when I press back-button, the fragments go to backstack. And when I resume it, it appears. But everytime on Resume, it is recreating the fragment and call onCreateView. I know it is a normal behavior of the fragment lifecycle.
This is my onCreateView:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.competitive_programming_exercise, container, false);
return rootView;
}
I want to stop those fragments from recreating. I tried with onSavedInstanstate but nothing is working. How can I accomplish that?
In the Activity's onCreateView set the savedInstanceState to null before calling the super method. You could also remove only the keys "android:viewHierarchyState" and "android:fragments" from the savedInstanceState bundle. Here is code for the simple solution, nulling the state:
#Override
public void onCreate(Bundle savedInstanceState)
{
savedInstanceState = null;
super.onCreate(savedInstanceState);
...
}
Iam using 5 fragments and working for me good as I was facing the same issue before..
public class MyFragmentView1 extends Fragment {
View v;
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
if (v == null)
v = inflater.inflate(R.layout.my_fragment_view_layout,
container, false
);
return v;
}
}
I put the view variable inside class and inflating it as new only if the view instance is null or otherwise use the one created before
You can't stop the fragment from being recreated, unfortunately. The best you can do is to remove the fragment in a transaction, after it has been restored but before it gets displayed.
If you know you are going to remove the fragment immediately you can reduce the performance hit of restoring the fragment by simplifying methods such as onCreateView() to return a dummy view, rather than inflating the whole view hierarchy again.
Unfortunately the tricky part is finding the best place to commit this transaction. According to this article there are not many safe places. Perhaps you can try inside FragmentActivity.onResumeFragments() or possibly Fragment.onResume().
I am in the process of making my first app for Android, and I have a Fragment that gets added to my Activity in the Activity's onCreate() method. The problem I am facing is that I am unable to find any of the views contained within the Fragment from the Activity's onCreate() method.
Other threads have suggested that this is because the Fragment has not yet been inflated, so findViewById() will return null for any views contained within the Fragment.
Here is what I mean:
Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("activity onCreate");
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
return;
}
initialiseUI(); // Fragment added to Activity
System.out.println("end of activity onCreate");
}
Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
System.out.println("fragment onCreateView");
return inflater.inflate(R.layout.event_log, container, false);
}
This prints the results:
activity onCreate
end of activity onCreate
fragment onCreateView
Because of this order, any attempt to access the views of the Fragment in the Activity's onCreate() method (using findViewById()) produces a NullPointerException, as the Fragment's onCreateView() only gets called AFTER the end of the Activity's onCreate().
Using the FragmentManger's executePendingTransactions() after adding the Fragment doesn't help.
Basically, I have been forced to put the problem code in the Activity's onStart() method instead of onCreate(), as onStart() happens AFTER the Fragment's onCreateView().
Does anyone what the standard practice here is, or how I can make my Fragment-View-accessing code work within the Activity's onCreate() method?
Update your views in onCreateView().
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.event_log, container, false);
TextView tv = (TextView) view.findViewById(R.id.text);
tv.setText("hello world");
return view;
}
Or if your changes depend on Activity your Fragment is attached to, use onActivityCreated().
#Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView tv = (TextView) getView().findViewById(R.id.text);
tv.setText(getActivity.getSomeText());
}