Execute public Method of Activity from Fragment - android

I have a Fragment, which should execute a (public) Method reset() from the Activity in the Fragment it is called from.
I found, for example, this page:
Calling Activity methods from Fragment
The other way there's no problem:
Input_tap Input_tap = (Input_tap) getFragmentManager().findFragmentById(R.id.input);
Input_tap.reset();
Does someone has any idea how to do it the other way?
and: Does the Method has to be public - its a "void" Method?

A Fragment can call getActivity() to retrieve the activity that is hosting it.
If there is only one possible activity that can host the fragment, just cast the Activity to the proper class (e.g., MyActivity) and call a method on it:
((MyActivity)getActivity()).someMethod();
If there might be more than one activity that can host the fragment, you are best served by implementing a common interface on all those activities, so you can cast getActivity()'s result to that interface:
((MyInterface)getActivity()).someMethod();

Related

MVP: Best practice to manage Activities and Fragments

I have an Activity with two Fragments. I decided to have one presenter for each "view". So 1 presenter for the main Activity, 1 for the first fragment, and 1 presenter for the second fragment.
I have uses-cases in which I don't know where which code goes.
The first is where to manage fragments with fragment manager ? Do I have to do calls like "beginTransaction().add" in the activity or in his presenter ?
The second is, when the user tap on a button in the activity, I've to do some things in the current fragment. Do I have to call the presenter of the activity which will call the fragment's method wanted, or directly in the method onClick in the activity I call this fragment's method?
PS: I don't want to use any lib/framework
The first is where to manage fragments with fragment manager ? Do I
have to do calls like "beginTransaction().add" in the activity or in
his presenter ?
Everything that is Android API related should be inside the Activity. So, beginTransaction() is a method of the FragmentManager and this is part of the Android API. The Activity is the contract between your app and the operating system. The presenter should not even know that it is used for an Android app. If you press a button inside the Activity for instance it goes like this:
Inside event handler method which is inside your Activity you do this:
Call activityPresenter.onButtonClicked() and it will call activityView.presentWhatTheButtonClickDid()
The second is, when the user tap on a button in the activity, I've to
do some things in the current fragment. Do I have to call the
presenter of the activity which will call the fragment's method
wanted, or directly in the method onClick in the activity I call this
fragment's method?
You would indirectly call the Fragment method via its presenter.
Inside event handler method which is inside your Activity:
Call activityPresenter.onButtonClicked() and it will call
fragmentPresenter.onButtonClicked() and it will calls
fragmentView.presentResult()
So, as you see the Activitiy's presenter needs to know the Fragment's presenter.
*You should not name your presenters with "activity" or "fragment" in its name to keep things abstract. I merely did this for simplicity.

can we pass the activity handle inside the fragment so as communicate to activity from fragment

i am trying to alter the activity content from fragment. for that i want to pass the activity handle inside fragment and do the required changes.
If i can do that why there is more difficult way of interface etc.
You can call getActivity() from the Fragment.
If you want to get your activity specifically you can cast it
((MyActivity) getActivity()).someMethod()
This will tightly couple your Fragment to your activity and prevent you using the fragment in a different activity easily so be careful.
Also you need to be careful with lifecycles and such as a fragment can become detached from an activity causing a NullPointerException from time to time. So it is recommended to wrap this in a null check

Which is the best approach to initialize an Interface. (Activity-Frament)?

I am new to the world of Android Programming,Here is my question.
Suppose I've an Activity named A and a Fragment named F. I know that the interaction between Activity and Fragment should be done through an Interface. I used to set the Interface in the onAttach() of Fragment like this
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = (MyListenerInterface) activity;
}
and now am heard about the Static Factory Method from here.
My question is : Which is the best approach to init. a listener ? onAttach() method or initialize the listener through the static factory method ,like this?.
public static MyFragment newInstance(MyListenerInterface mListener) {
MyFragment f = new MyFragment();
this.mListener = mListener;
...........
return f;
}
I think, it is better to initialize the listener through the static factory method instead of casting from the activity,so we could avoid a null pointer exception.
Yes you do not need to cast anything via factory, but onAttach is better in my opinion because you have less chance of leaking an activity context. Let's say you make an instance with the factory and never use that fragment, it will leak the context of the Activity and there by everything in it. Also don't forget to destroy the interface in the onDetach.
Also you can have many instances of that fragment and with option one, they will all have the same listener, not good.
Also you should make what you could call a BaseActivity, an abstract activity all other extend from and define the interface methods there and you will avoid always casting to a lot of different classes. This will also come in handy if you need to quickly change something in every activity of your app.
First option (Initializing the listener in the OnAttach()) is a better one because
In first option the MyListenerInterface is an non-static variable, so each fragment has its own listener.
Whereas the second option's MyListenerInterface variable is an static that is reference maintained at the class level and common for all the other fragment instances this causes the problem when you need the same fragment in different activity then the listener of one activity will be overrided with another activity.

onAttach(Activity activity) what is this activity in a fragment inside another fragment

It sounds me a confusing Question. What is the Activity Object in onAttach method of a fragment which is nested inside a parent Fragment?
I know I can communicate to the parent fragment by using getParentFragment() method.But I want to know if this activity object in the onAttach returns the FragmentActivity instance or not, so as to have a direct communication (by using interface callback) from a nested fragment to the FragmentActivity.
Sorry for my bad English. I tried my best to convey my thoughts.
Yes, the Activity object is your FragmentActivity. Check the docs here: http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity)
You can also get the activity by using getActivity() anywhere in your fragment (but be aware it only works after onActivityCreated has been called)
Yes it is the FragmentActivity that hosts the Fragment (directly or nested in another Fragment). There is more information about communicating with the parent FragmentActivity here.

Send message to TabHost's Fragment from Activity

I have an Activity which contains a Fragment in it. The Fragment contains a TabHost which contains several other Fragments. I need to send a message from Activity to one of TabHosts Fragment, what is the best way to do that?
You can the Observer-pattern implement an Observer interface in your activity, then you can register your fragment as an Observable. Now if you want to sent data to the activity you can use notifyObserver(object dataYouWantToSend) and call hasChanged().
This should be recognized by your activity where the interface method update will receive the data.
I recommend to create a custom observable object there you can override the notifyChange method and directly add the hasChanged() method. The overwritten method would look like this.
notifyChange(Object data) {
super.notifyObservers(data);
setChanged();
}

Categories

Resources