I can easily detect when Fragments
are attached to Activity
via Activity.onAttachFragment()
But how can I detect in Activity
that some Fragment
is detached from activity?
There is no Activity.onDetachFragment()
Is subcclasing Fragment
and write some code to notify Activity
about that state is the only solution?
you can use interface for communicating between Fragment
and Activity
something like this :
public Class MyFragment extends Fragment {
FragmentCommunicator communicator;
public void setCommunicator(FragmentCommunicator communicator) {
this.communicator = communicator;
}
@Override
public void OnDetach() {
communicator.fragmentDetached();
}
...
public Interface FragmentCommunicator {
public void fragmentDetached();
}
}
and in your activity :
public Class MyActivity extends Activity Implements FragmentCommunicator {
...
MyFragment fragment = new MyFragment();
fragment.setCommunicator(this);
...
@Override
public void fragmentDetached() {
//Do what you want!
}
}
Edit:
the new approach is setting interface instance in onAttach
.
public void onAttach(Activity activity) {
if (activity instanceof FragmentCommunicator) {
communicator = activity;
} else {
throw new RuntimeException("activity must implement FragmentCommunicator");
}
}
now there is no need to have setCommunicator
method.
Mohammad's original answer is close to I would do. He has since updated it to leverage a mechanism provided by Android - Fragment.onAttach(Context context)
.In that approach, the fragment grabs components (ie, the activity) from the system and calls into it. This breaks inversion of control.
Here is my preferred approach:
public class MyActivity extends AppCompatActivity {
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment instanceof MyFragment) {
((MyFragment) fragment).setListener(mMyFragmentListener);
}
}
private final MyFragment.Listener mMyFragmentListener = new MyFragment.Listener() {
@Override
public void onDetached(MyFragment fragment) {
fragment.setListener(null);
}
// implement other worker methods.
};
}
public class MyFragment extends Fragment {
@Nullable
private Listener mListener;
public void setListener(@Nullable Listener listener) {
mListener = listener;
}
public interface Listener {
void onDetached(MyFragment fragment);
// declare more worker methods here that leverage the connection.
}
@Override
public void onDetach() {
super.onDetach();
if (mListener != null) {
mListener.onDetached(this);
}
}
}
In this solution, the fragment doesn't dictate it's surroundings. Some control is given the to fragment in that it breaks the connection itself. We also already don't own the detaching of the fragment anyways, so clearing the listener is really just cleanup.
Here is an alternative approach that is more explicit, less prone to developer error, but also creates extra boiler plate (I prefer the previous approach because the goodbye handshake feels like an unnecessary distraction):
public static class MyActivity extends AppCompatActivity {
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment instanceof MyFragment) {
((MyFragment) fragment).setListener(mMyFragmentListener);
}
}
private final MyFragment.Listener mMyFragmentListener = new MyFragment.Listener() {
@Override
public void onDetached(MyFragment fragment) {
fragment.setListener(null);
}
// implement other worker methods.
};
}
public static class MyFragment extends Fragment {
@Nullable
private Listener mListener;
public void setListener(@Nullable Listener listener) {
mListener = listener;
}
public interface Listener {
void onDetached(MyFragment fragment);
// declare more worker methods here that leverage the connection.
}
@Override
public void onDetach() {
super.onDetach();
if (mListener != null) {
mListener.onDetached(this);
}
}
}
You have a callback in the fragment life cycle. onDetach() is called when fragment is no longer attached to activity.
An alternative would be:
mFragmentManager.findFragmentByTag("Tag").getView()
If the view is null the fragment must be detached.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With