If I'm inside a Fragment how can I call a parent's activity?
Yes, Its right by calling getActivity and cast it with parent activity to access its methods or variables ((ParentActivityName)getActivity())
Try this one.
ParentActivityName is parent class name
2021 UPDATE
As it's told in the comments, Fragment#onAttach(Activity) is deprecated starting from API 23. Instead:
#Override
public void onAttach(Context ctx) {
super.onAttach(ctx);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
// Only attach if the caller context is actually an Activity
if (ctx instanceof Activity) {
mCallback = (OnHeadlineSelectedListener) ctx;
}
} catch (ClassCastException e) {
throw new ClassCastException(ctx.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
ORIGINAL ANSWER
The most proper way is to make your Activity implement an Interface and use listeners. That way the Fragment isn't tied to any specific Activity keeping it reusable. Into the Fragment:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
That way, you make the Activity listen to the fragment when it's attached to it.
See also:
http://developer.android.com/training/basics/fragments/communicating.html
Simply call your parent activity using getActivity() method.
CardView cardView = (CardView) getActivity().findView(R.id.your_view);
Related
I have a fragment that can either be attached to an Activity or a parent fragment. This fragment has an interface that must be implemented by anyone it is attached to. For activities, this is quite simple:
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof Activity){
Activity activity =(Activity) context;
try {
mCallback = (OnMyListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() +
" must implement OnMyListener");
}
}
}
However, I am unable to set the mCallback listener for other Fragments that are hosting this particular Fragment.
You can't directly communicate between 2 fragments, it has to go thorough the activity hosting it (and I saw you already implemented the first half).
After the activity received the data from sender fragment, you can send it to the receiver fragment by resolving the receiver fragment's reference first, using:
ReceiverFragment fragment = ( ReceiverFragment) getSupportFragmentManager().findFragmentById(R.id.receiver_fragment_id);
if it's null then you need to instantiate it first and pass the data using fragment.setArguments(Bundle), otherwise you can directly call the member function of the receiver fragment.
Check: https://developer.android.com/training/basics/fragments/communicating.html
I have one MainActivity and two fragments namely Input.java and Output.java. I want to access the textview located at output_layout in Input fragment (More precisely, if I click on the button in input_layout, the textview of output_layout should change). How can i do this? I am calling these input_layout and out_put layout dynamically in main_activity.
As I am beginner, pardon my ignorance. Your help will be highly appreciated. Thanks in advance.
Try use interfaces.
For example.
public interface OnOutputFragmentTextChanger {
public void onChangeText(String what);
}
In onAttach method of Input.class do next:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnOutputFragmentTextChanger) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnOutputFragmentTextChanger");
}
}
And in yours OnClickListener call mCallback.onChangeText("Foooo");
Next in Output class create method
public void updateInputView(String what)
{
mTextView.setText(what);
}
Next implement OnOutputFragmentTextChanger in Activity and Override method onChangeText(String what):
public class MainActivity extends FragmentActivity implements OnOutputFragmentTextChanger
{
//do somwthing
#Override
public void onChangeText(String what)
{
InputFragment inputfragment = (InputFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment); // or try findFragmentByTag
if (inputfragment != null)
{
inputfragment.updateInputView("some string");
}
}
}
you can declare the TextView in the input layout as public static in the corresponding fragment and directly access it in other fragment where you want to set the value onclick of the button
Android best practices for fragment-fragment interaction (described here and here) forces the Activity to implement a listener defined by the child fragment. The Activity then manages the communication between fragments.
From my understanding this is to keep the fragments loosely coupled from each other. However,
Is this also the case for nested fragments? I can imagine it might make sense for a nested fragment to report directly to it's parent fragment instead of the Activity.
If a nested fragment has its parent fragment implement it's listener, how would one (or should one) require the parent fragment to do this. In other words, is a similar to the paradigm to the following but for Fragments:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
If anyone wanted an example of an implementation that ensures parent context implements the callbacks while not caring whether it is an activity or fragment, the following worked for me:
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof Callbacks) {
mCallbacks = (Callbacks) context;
} else {
if (getParentFragment() != null && getParentFragment() instanceof Callbacks) {
mCallbacks = (Callbacks) getParentFragment();
} else {
throw new RuntimeException(context.toString()
+ " must implement " + TAG + ".Callbacks");
}
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
Enjoy!
As long as you define an interface in the fragment, you can have the parent activity or parent fragment implementing it. There is no rule that says fragment should not implement interface of a child fragment. One example where this make sense is that fragment A has two children Fragments B, C. A implements B's interface, when A gets a call back, it might need to update fragment C. Exactly the same thing with activity, just different level.
You can implement the same pattern for child/parent interactions using getParentFragment(). The parent fragment refers to whichever fragment has this one added through its ChildFragmentManager. If this Fragment is attached directly to an Activity, this method returns null.
I have a question I hope someone can solve it.
I have 4 fragments for 1 activity, but just 2 of them are displayed, so I have buttons to navigate between these fragments.
All clicks must be executed in the activity, so this knows which fragment ahs to replace, so all "OnClickListener" must to implement the "OnclickListener" of the activity.
How can I solve this? Thank you!
There is a standard solution for this:
Define an interface, say ClickCallbacks:
interface ClickCallbacks {
void onClick(stuff... );
}
In each fragment, implement onAttach, like this:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try { clickListener = (ClickCallbacks) activity; }
catch (ClassCastException e) {
throw new ClassCastException(
activity.toString() + " must implement ClickCallbacks");
}
}
Finally, implement the interface in your Activity.
This is described in pretty clear detail in the Fragment documentation here: Fragments
I've been working a lot with fragments lately and I was just curious as to what the best practice is for using a reference to a fragment's parent activity. Would it be better to keep calling getActivity() or have a parentActivity variable initialized on the onActivityCreated callback.
This is actually included in the official Android document on Fragments. When you need the context of the parent activity (e.g. Toast, Dialog), you would call getActivity(). When you need to invoke the callback methods in your Fragment's interface, you should use a callback variable that is instantiated in onAttach(...).
public static class FragmentA extends ListFragment {
ExampleFragmentCallbackInterface mListener;
...
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (ExampleFragmentCallbackInterface ) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement ExampleFragmentCallbackInterface ");
}
}
...
}
Source
getActivity() is best. You need not maintain a variable to store (always, til app cycle!). If needed invoke the method and use! :)
If you are in the fragment which is called from some activity, to get the reference to parent activity you can call it inside onViewCreated() or later hook methods of fragment directly by, it is just to make sure that parent activity is not null
getActivity()
If you want to really make sure you need to check first
if (getActivity() != null){ // then your logic with getActivity()}