I have some problems initializing some values for some views in my Android Activities cause for me to be able to get the views I have to wait for the activity layout aswell as the fragment layout to be inflated until I can initialize the views values. I know i can initialize the views in the fragments OnCreateView but I would like to avoid that and instead have some kind of method that is run right after the onCreates/onCreateView's are done.
Is this possible if so how? And what is the best practice of modifying/initializing views?
Thanks in advance
Unless you have a special case you should not deviate from the lifecycle of a Fragment or Activity.
Anyway if so, Calling a method as you asked for, look at the MainActivity class on this example. It uses a Handler to do work on the UI Thread
You could do this in the onStart() or onResume() methods, which are called after onCreate(), but also after stopping or pausing of the Activity.
For more detailed Information have a look at the Activity Documentation
You should also try to work on the formatting of your question, I'm not sure whether I understand the problem correctly, or not.
You can use the way mentioned over here. It's cleaner.
you put the following method in the fragment.
public void initFragment() { //Do your required things here }
After creating the object for the fragment (for instance example given below)
mFragmentManager = getSupportFragmentManager();
mIssDetailsListFragment = (IssDetailsListFragment) mFragmentManager
.findFragmentById(R.id.fragment_outlet_list);
you call the method initFragment() (Sample code given below)
mIssDetailsListFragment.initFragment()
Related
Hello I'm new to the android ecosystem and wanted to inquire about best practices when it comes to defining a fragments content
currently I'm opening a connection to my database aswell as initialising onClick listeners in my fragment's onCreateView but I'm also aware that there exists onViewCreated and onCreate similar to a regular activity, while I'm familiar with where everything is placed in an activity, I'm not as sure about fragments, can someone help me out?
-thanks
onCreateView()
This is the place where you initialize your views (findViewById()) / attach listeners to them.
From android docs:
Called to have the fragment instantiate its user interface view
onCreate()
It's better to move the code that connects to the database here - code that doesn't depend on UI elements.
You can read more in the official docs here.
I have 3 fragments that are contained within the main activity via a ViewPager. What I'm trying to do is allow myself to call methods on objects of those fragment classes from different lifecycle callbacks in the main activity, namely onRestart(), so that I can refresh their content via a backend call. To be more specific, one of the fragments contains a "live feed" of images that people are posting, and the user gets to this posting activity via one of the fragments.
Right now, the problem I'm trying to solve is that when a user goes to this posting activity and puts up a picture, the live feed in the fragment they come back to isn't getting refreshed. To do this, I would need to call my backend and UI update methods in that fragment from the main activity's onRestart().
But I'm running into these null pointer exceptions -- here's what the code looks like in the fragment:
public void refreshUI(){
activity = getActivity();
appContext = ThisApp.appContext();
view = getView();
peopleHeader = (TextView) view.findViewById(R.id.people_header);
peopleLinearLayout = (LinearLayout) view.findViewById(R.id.local_people_linearlayout);
..... (various other instantiations)... }
The NPEs are coming either from getActivity() or some of the UI instantiations. I call this code from onActivityCreated() and it works as expected. However, if I try to call this code again on my fragment object from onRestart(), I crash.
What's happening? Can't figure out why this would go bad on me.
Thanks so much.
When your Activity is destroyed and recreated, your Fragments are also destroyed and recreated with it. You can have a look at the Fragment/Activity lifecycle explanation here.
What this means is that the reference you keep disappears, the Fragment is there but it is another object. You need to get a reference to this new object.
You can check this answer on how to do that. It explains getting references to Fragments created by a ViewPager adapter.
Calling setHasOptionsMenu(true) from constructor, which is obviously called even before onCreate(), works perfectly! Can I do that? What will be problems?
Check here fragment - Android
Applications should generally not implement a constructor. The first
place application code can run where the fragment is ready to be used
is in onAttach(Activity), the point where the fragment is actually
associated with its activity. Some applications may also want to
implement onInflate(Activity, AttributeSet, Bundle) to retrieve
attributes from a layout resource, though should take care here
because this happens for the fragment is attached to its activity.
You may want to use another lifecycle event for this.
Yes, you can call setHasOptionsMenu(true) from the constructor.
I have a button that I want to change its value often, so my Activity has a private variable :
private Button p1_button = (Button)findViewById(R.id.firstbut);
This simple line makes my app crash. If I put inside the onCreate it works and I can interact with the button (change text etc).
EDIT : I think I found the reason. I should initialize AFTER setcontentview ?
EDIT: Thank you for the constructive answers. I have now a different problem I removed the initialization and I did it on onCreate and it works (But I keeped the p1_button declaration as a private field). But when I tried to modify the button in a different method of my activity (just changing the text), it crashes again. So the return value of findViewById is "local" to the method where it is called and I should setcontentview in every method that access UI elements ?
Do not call findViewById() until after you call setContentView(). Otherwise, the widget will not exist.
More generally, do not call inherited methods on Activity until after super.onCreate(), unless specifically advised to do so.
It depends where you are calling this line.
http://i.stack.imgur.com/6EQaU.png
The onCreate() method contains a call to setContentView() and before this is called, Android has no idea what to do with your button as it hasn't been inflated yet!
Therefore as a really easy rule of thumb, always make sure setContentView (or if you're dealing with fragments onCreateView()) have been called and completed. Only then will findViewById() work.
If you would like further guidance, please post some code in which the crash occurs.
edit: I tried to add the image properly but don't have enough rep.
To understand this you need to know the Activity lifecycle. You are trying to look a view which has not yet been created by Android.
As per the android lifecycle explained here "http://developer.android.com/training/basics/activity-lifecycle/starting.html". In onCreate() method the activity is created and you can access different views of the activity. If you will try to look for view before onCreate() the app will crash as it does not know whether that view exists or not.
Situation
My activity waits on an Async operation and after it hears back from async operation, it needs to pass information to 2 fragments inside it.
Requirement
1. Both fragments need their onCreateView calls to be done for them to have their layouts loaded,
2. They need for themselves to be attached to their activity so that getActivity() works.
I wrote a setData() method in both the fragments and am looking for the "correct" place in the activity's lifecycle to invoke them.
onCreate() of the activity does not work, onStart() of the activity does not work and onStart() of the fragment does not work.
Nothing works, what am I missing here?
The official documentation for the Fragment lifecycle explains this clearly - please refer to it and then ask follow-up questions if something is unclear.
This Image will be helpful to understand both life cycles together.
As many people complaints and it is somewhat valid argument that this life cycle is too complicated, in Google I/O 2018,They have suggested to use Architecture component Framework. Please check this Docs
when you are at Activity2---->backpress--->Fragment2(Activity1)---means Activity1 again attach from fragment2 so on OnAactivityCreated() method Activity1 is completely loaded ....so at that we can call setData() method of your Activity1...
onAttachFragment()-activity is called before onCreate()-activity and after onAttach()-fragment
Call onDestroy on onStop of your fragment. This should call onCreate when the fragment is launched.
Let me know if works as an ideal solution for your problem.