I really need your help here.
I have two Fragments:
1. Fragment A
2. Fragment B
One Interface
1. onSkillsSelectedListener ( method onDoneClicked )
Fragment A implements onSkillsSelectedListener and when "DONE" button is called in Fragment B, i call onDoneClicked() , and Fragment B is destroyed.
Now method onDoneClicked in Fragment A is called before even OnResume in Fragment A is called so i cannot make any changes in my Layout.
How to fix this issue?
The fragments onResume() or onPause() will be called only when the Activities onResume() or onPause() is called. They are tightly coupled to the Activity.
http://developer.android.com/guide/components/fragments.html#Lifecycle
You need to find another way to implement this.
I FIX IT
Just changed the way i called my Fragment B
from replace to add
So now Fragment A is not even Paused and callback is working!
Cheers!
Related
When I go from Fragment A to B, Fragment B's onResume() is called first and then Fragment A's onPause() is called. Which is different from Activity lifecycle.
How to solve this?
Check out - https://androidlearnersite.wordpress.com/2017/02/27/fragment-lifecycle-during-fragment-transaction/ ..
It explains fragment lifecycle during fragment transaction with latest appcompat version.
As per latest appcomat version, if setAllowOptimization() is set to true then during replacing fragments onResume() is called before onPause() otherwise onPause() is called before onResume().
setAllowOptimization() is used to set whether or not to allow optimization operation within and across transactions.
I create an application as below:
Main activity includes FragmentTabHost which includes two ContainerFragments which include two Fragments separately.
Now I startActivityForResult from UserFragment, but onActivityResult in UserFragment cannot be called! What's wrong? How to resolve?
The project in https://github.com/VictorS-Zhao/TabHostAndNestedFragment.
Thanks in advance!
Supplement:
This is a strange behavior, the 1st nested fragment Community Fragment's onActivityResult can be called every time, but the 2nd nested fragment User Fragment's cannot be called. When startActivityForResult from UserFragment, but the onActivityResult in CommunityFragment is called.
Solution:
Finally I found solution in onActivityResult() not called in new nested fragment API
According to this answer, should override onActivityResult in ContainerFragment, and use getParentFragment().startActivityForResult in UserFragment. That's nice!
Provided that the UserFragment is your child fragment (a child of ContainerFragment), onActivityResult method does not execute once you return from your activity which has been started with
startActivityForResult.
It was a bug in the support library, I came over similar situation a while ago and it still was not fixed. Honestly, I am not sure whether it is fixed at the moment, you have to find out.
Here is a solution describing how to handle that:
http://inthecheesefactory.com/blog/how-to-fix-nested-fragment-onactivityresult-issue/en
https://gist.github.com/artem-zinnatullin/6916740
Basically the easiest way to make onActivityResult method executed in the child fragment is to start the activity from Activity level getActivity().startActivityForResult() or Parent Fragment getParentFragment().startActivityForResult() and notifying manually every fragment belonging to the calling Activity about invoked Activity's result.
Alternatively you can use some open source:
https://github.com/nuuneoi/StatedFragment
Hope that helps somehow.
Response to the Supplement:
Just as stated above, BaseContainerFragments belong to MainActivity, for those fragments onActivityResult method is called normally.
The problem begins when a child fragment is added to a parent fragment. For the child fragments onActivityResult is not called and you have to handle it manually in the Activity or the ParentFragment.
See :
onActivityResult() not called in new nested fragment API
onActivityResult is not being called in Fragment
So I have a fragment A which has a button to open another a fragment B. In fragment B I can pick some options, which is bundled into an Bundleobject. When I exit from fragment B, I want to refresh a TextView in fragment A.
Right now I'm using dismiss() method to remove the fragment, and then call back the fragment again so that onCreateView() is called. It works fine, but I don't want the animation where the fragment windows is run. So I like to not use dismiss() to remove the fragment instead I want to keep it on the Activity, but I need to know how I can refresh fragment A. I've tried overriding onActivityCreated() but it didn't result in the action I wanted.
So I wonder what's the approach if I want to refresh fragment A without having to dismiss it first so that onCreateView() can be called again.
I can attach code if needed. But maybe just an explanation is enough here?
you can use the life cycle function onResume() in fragment A to update the textview.
You can create your own Listener interface ( example how to do it or this) that listens when you remove your fragment, and you can get the event on Fragment A where you can setText to your TextView.
I have been asked an interview question: Can a fragment exist without activity? I searched for answers but didn't get a proper answer and explanation. Can someone help?
Yes, you can do this anywhere:
new YourFragment();
As fragments must have a parameter-less constructor.
However its lifecycle doesn't kick in until it is attached. So onAttach, onCreate, onCreateView, etc. are only called when it is attached. So most fragments do nothing until they are attached.
It can exist as an object in memory (by creating it with new), but it needs to be attached to an Activity in order to appear on the screen, assuming it has any UI (fragments don't have to have UI).
A Fragment can exist independently, but in order to display it, you need the help of an Activity. The Activity will act like a container for the Fragment(s).
A fragment is not required to be a part of the Activity layout; you may also use a fragment without its own UI as an invisible worker for the Activity but it needs to be attached to an Activity in order to appear on the screen.
As soon as you create an instance of the Fragment class, it exists, but in order for it to appear on the UI, you must attach that fragment to an activity because a fragment's lifecycle runs parallel to an activity's lifecycle. Without any call to Activity's onCreate(), there will be no call for onAttach(), onCreate(), onCreateView() and onActivityCreated() of fragment and so it can't be started.
I read above top rated answer , i am not disagreeing but android already provides to make independent fragment without activity DialogFragment , which extends fragment . if you want show in full screen first extends DialogFragment then
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_FRAME, android.R.style.Theme_Holo_Light);
}
Android app must have an Activity or FragmentActivity that handles the fragment.
Fragment can't be initiated without Activity or FragmentActivity.
I have followed the ABS example of FragmentTabsPager, but I'm facing this problem:
Activity A has two fragments: F1, F2 which are added in onCreate() method of the A with use of the TabsAdapter.
Activity A has the option to refresh fragments which is done according to
http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
Activity A has the option to launch Activity B, which adds item to F1 (F1 thus, needs to be updated)
However, after finishing B, the fragments are not attached to A anymore. After some debugging, I found that the onCreate() method of A is called after finishing B with savedInstanceState containing this entry:
android:support:fragments=android.support.v4.app.FragmentManagerState$41bfffe0
My understanding is that FragmentActivity saved the fragments before launching B and after relaunching A, it tries to restore them. With a little of tracing I found that after finishing B, these actions are called:
Activity A: constructor called
Fragment F1: constructor called
Fragment F2: constructor called
Fragment F1: onAttach
Fragment F1: onCreate
Fragment F2: onAttach
Fragment F2: onCreate
Activity A: onCreate
Activity A: TabsAdapter created
TabsAdapter: addTab android.widget.TabHost$TabSpec#41d949f8
Fragment F1: constructor called
TabsAdapter: addTab android.widget.TabHost$TabSpec#41d965d0
Fragment F2: constructor called
Fragment F1: onActivityCreated
Fragment F1: onCreateLoader
Fragment F2: onActivityCreated
Fragment F2: onCreateLoader
Activity A: onStart
Fragment F1: onResume
Fragment F1: onCreateLoader
Fragment F2: onResume
Fragment F2: onCreateLoader
Activity B: onStop
Fragment F1: onLoadFinished
Fragment F2: onLoadFinished
There are 2 instances of each fragment, and the showing fragments are not attached to activity.
How can I solve this? What am I doing wrong? Maybe if there was a way how to get the restored fragments?
Thanks in advance
If I am understanding this correctly, here is what I would suggest:
Since Fragments F1 and F2 live in Activity A, Activity B should not create, or attempt to interact with either Fragment.
Have Activity A start Activity B using startActivityForResult, and have B pass back the item (to be added to Fragment F1) to A.
Activity A should handle sending the new item to Fragment F1 using an interface (like you've done).
Upon receiving the new item (in your interface method) from Activity A, Fragment F1 should then update its data and refresh its Views.
Another thing to note, ensure that your Activity A only adds your Fragments once in onCreate, it can use the savedInstanceState to know if it is being recreated or if it's the first creation of it. See http://developer.android.com/training/basics/fragments/fragment-ui.html.
Edit
Ah now I see more of what you are asking. There are several ways you can go here.
Use the FragmentManager and the tag trick to get the Fragments out of the ViewPager, and update them as needed.
This is slightly more dangerous as it will return Fragments that may not be in onResume and need to be checked before being interacted with.
Decouple the model from the controller, as in put your data into a static singleton, SQLite DB, or even preferences. This would allow other portions of the app to access and edit the data, without the need of passing it around.
In onResume, your Fragments would then need to check and update their data, in case it had been changed.
Your Activity will also need to give them a refresh signal via an interface method if the Fragments are already in onResume when the change occurs.
OR, use a Loader in your Fragments to monitor the data set and have it autoupdate the Fragment's UI via interface callbacks.