Android Call Fragment Method from Fragment - android

I have 4 Fragments and I am trying to click a button on FragmentA and call a method that changes the visibility of some views on FragmentB and populate it.
I tried an interface, but I can't seem to get it to work between 2 fragments. I can call the interface method from a fragment if I implement it in the activity, but I can't implement it in a fragment and call it in a fragment.
Is there a different way to do this? I don't think I can use the static keyword.

I am suggesting you can use broadcast receiver its, good to perform action anywhere and easy to use.
In your first fragment you can define receiver and from another fragment, you can send broadcast or action.
Example are following.
Write following code in your first fragment in which you want to update view,
private void registerReciver() {
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals("UPDATE_FRAG_A")) {
// here you can fire your action which you want also get data from intent
}
}
};
IntentFilter intentFilter = new IntentFilter("UPDATE_FRAG_A");
getActivity().registerReceiver(broadcastReceiver, intentFilter);
}
And In your second fragment write following code for fire action,
Intent intent=new Intent();
// Here you can also put data on intent
intent.setAction("UPDATE_FRAG_A");
getActivity().sendBroadcast(intent);

Assume that all the fragments are in the same activity.
Define a interface in FragmentA, which is a Listener
Expose what you want to do in FragmentB via a public method
Implement FragmentA's interface in the parent activity by calling the public method of FragmentB
For more inforamtion,see Communicating with Other Fragments

Related

popBackStack with Pass Parse Object

I have an Activity A. Activity A calls fragment frag1. frag1 calls fragment frag2. Lastly frag2 calls frag3.
When I click on a button in frag3, I want to call frag1, pass and parse an object from frag3 to frag1. I tried to do this with an object bundle sent from frag3 to frag1.
I see that there is a popBackStack() method. However, I am a little confused on how this would work. Is it safe to use this method?
I do not know how to do it.
Thanks in advance.
Use Event Bus pattern for passing data(events) between fragments. Then work with you fragment stack in usual way.
There are several popular libraries that implement event bus. I personally prefer
EventBus
Otto
use Local Broadcast for this.
write Broadcast receiver on fragment 1,
On apply button of fragment 3, broadcast your data , and then pop fragment 3
example-
private final BroadcastReceiver myLocalBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
;
Bundle bundle = intent.getExtras();
if (bundle != null) {
get data from bundle
}
};
on fragment 3(apply button):
Intent localBroadcastIntent = new Intent(Constant.MY_ACTION);
Bundle bundle = new Bundle();
bundle.put("your data);
localBroadcastIntent.putExtras(bundle);
LocalBroadcastManager myLocalBroadcastManager = LocalBroadcastManager.getInstance(getActivity());
myLocalBroadcastManager.sendBroadcast(localBroadcastIntent);
getActivity().getSupportFragmentManager().popBackStack();

Listen to same result from different Android Fragments

There are 2 Fragments
I'm calling a service from Fragment 1. I have a ResultReceiver in Fragment 1 which listens to the result and onReceiveResult will call method1().
I want a ResultReceiver in Fragment 2 to listen to the same response but onReceiveResult will be calling method2()
How can I achieve this?
You could specify an interface:
interface Receiver {
void onResult();
}
Have your two Fragments implement this interface. Fragment1's implementation simply calls method1(), and Fragment2's implementation simply calls method2():
public class Fragment1 extends Fragment implements Receiver {
// Remember to register and remove the receiver (e.g. in onAttach and onDetach respectively).
private MyReceiver mBroadcast = new MyReceiver(this);
public void onResult() {
this.method1();
}
}
public class Fragment2 extends Fragment implements Receiver {
// Remember to register and remove the receiver (e.g. in onAttach and onDetach respectively).
private MyReceiver mBroadcast = new MyReceiver(this);
public void onResult() {
this.method2();
}
}
Then specify the BroadcastReceiver as a standalone (or inner static) class such that both Fragment1 and Fragment2 will be able to instantiate it:
public class MyReceiver extends BroadcastReceiver {
private Receiver mFragment;
public MyReceiver(Receiver fragment) {
mFragment = fragment;
}
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(YOUR_ACTION) {
mFragment.onResult();
}
}
}
I don't think that you can receive results in two different fragments simultaneously.
But there are many ways to achieve this..
1.
I believe the easiest way will be to use object reference..
There are two possibilities.. Either create a static method in Fragment 2 and call it from fragment 1 from onReceiveResult(). Or Create an object of Fragment 2 in fragment 1 and from fragment 2 , assign that it is the same as the instance created by fragment1. Then just call
object_of_frgament2.method2() from the onReceiveResult() of fragment 1.
2.
Using interface.Create a custom interface and make the Fragment 2 implement the interface and create an instance of the interface in Fragment 1.
and within onReceiveResult() of Fragment1 you can call the interface method.
While implementing the interface, you can get the result in fragment 2 in the interface method.
Just call method2() from the function....
3.Using Broadcast Receiver..
Create a custom broadcast receiver and make all the fragments/activities which need the results to listen to it. and within onReceiveResult() of Fragment1 just broadcast the result..
I believe there are still other ways to do it..
just pass into your service two different ResultReceiver's ... If the service is already started calling startService(Intent) again just makes you call onStartCommand(...) and then you can set your resultReciever each time. So you can keep an array of resultreciever's if you want.
saying that, i would never do it this way. Research Java Observer pattern. Java has a default implementation of the Observer pattern. Here is a link

Modifying view inside a fragment inside other fragment doesn't works

I am trying to modify views inside a fragment1 from other fragment2, parent of fragment1, calling a public method of fragment1, but doesn't works.
In the container fragment a do this:
AddressEditSubviewFragment profesionalEditFragment = new AddressEditSubviewFragment();
notificationsEditFragment = new AddressEditSubviewFragment();
fragmentTransaction.add(R.id.addresses_edit_fragment_notifications_edit_fl, notificationsEditFragment);
fragmentTransaction.commit();
CheckBox notCB = (CheckBox) view.findViewById(R.id.addresses_edit_fragment_notifications_same_cb);
notCB.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
notificationsEditFragment.disableEnableEdit(true);
}
});
The method in the fragment to change the state of the views is this:
public void disableEnableEdit(boolean disable) {
streetET.setKeyListener(null);
streetET.setCursorVisible(false);
streetET.setPressed(false);
streetET.setFocusable(false);
numberET.setFocusable(!disable);
numberET.setEnabled(!disable);
numberET.setText("pruebas");
floorET.setVisibility(View.GONE);
buildingET.setFocusable(!disable);
buildingET.setEnabled(!disable);
pcET.setFocusable(!disable);
pcET.setEnabled(!disable);
}
When I call the method from the container fragment it enters in the method, but not change nothing. Why is this thing happens?
you can't and shouldn't have fragments communicate directly with one another. all communication between them must go through the activity or the parent fragment (if it's hosting both of them).
There are a few ways to do this. here's one method.
I personally prefer working with broadcastreceivers. The method is basically:
Have fragment1 call some method in the activity.
Have that method sent a broadcast on some intent filter when its done.
Implement a broadcast receiver on fragment2, that does stuff when receiving a broadcast.
Have fragment2 register and unregister the receiver on said intent filter as you please (usually done on the onResume and onPause respectfully).
Tell me if my explanation wasn't clear enough, I'll provide a working code example.
Good luck! :)
--- EDIT ---
Ok, after understanding you're trying to call a method in a child fragment from its parent fragment, here's a method with broadcast receivers that should work:
parent fragment sends a broadcast on some intent filter whenever you need to call the method in the child fragment.
Intent intent = new Intent();
intent.setAction(some_string);
getActivity().sendBroadcast(intent);
implement a broadcast receiver in child fragment that calls that method in its onReceive().
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
doStuff();
}
};
register the receiver to the intent filter in the child fragment's onResume(), and unregister it in the child's onPause().
getActivity().registerReceiver(receiver, new IntentFilter(some_string));
getActivity().unregisterReceiver(receiver);
Finally, I found the problem. The problem was that I had two cheboxes whit the same id in the parent fragment. And when I check a check box doesn't work well. Sorry for the question.

Sending data from one tab to another which contains a spinner

I want to send data from one tab to another. The one which will receive the data contains a spinner. When that data is passed on, I want to the spinner to change its selection to the one given within the data (it'll be the same as one of the spinner items).
Any ideas how I can use Bundle to do this?
is this in same activity or in a new activity ?
Same activity:
make an onClickListener and change the items in the spinner.
New Activity:
use
Inten intent = new Intent(yourclassname.this, targetClassname.class);
intent.putExtra("ID",DATA);
this.startActivity(intent);
it would help if you provide some code, but for now I hope this helps
As option make array holding data for a spinner static and then create a static method in you destination activity something like this:
public static void setSpinnerData (String[] data) {
spinnerData = data;
}
Then call something like this YourActivity.setSpinnerData (myArray);
Alternativerly you can consider saving data to the application object which is the same for all activities.
You may send the data (something small like a string or an ID) using a broadcast.
In the tab where the data is generated
final Intent i = new Intent(IConstants.UPDATE_SPINNER);
i.putExtra(IConstants.DATA_UPDATE, data);
this.sendBroadcast(i)
IConstants.UPDATE_SPINNER and DATA_UPDATE are just Strings used to identify your message by the receiver. You may also put them in your main activity instead of the interface I used.
In the tab with your spinner, declare an inner class for a broadcast receiver, it can access the spinner of the outer class.
private final class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
if( IConstants.UPDATE_SPINNER.equals(intent.getAction()) ) {
final String data = intent.getIntExtra(IConstants.DATA_UPDATE, "");
// update your spinner
return;
}
// process other messages ...
}
}
Register the broadcast receiver like this, e.g. in onCreate() or onResume()
this.broadcastReceiver = new MyBroadcastReceiver();
final IntentFilter f = new IntentFilter(IConstants.UPDATE_SPINNER);
// for more actions you can add them like this:
// f.addAction(IConstants.UPDATE_ONOTHER_WIDGET);
this.registerReceiver(this.broadcastReceiver, f);
Remember to unregister in onDestroy() or onPause().
Another option would be to use a handler and send messages to the handler. However, you would need the handler, which is located in the receiver, to be accessible in the sender. This way your fragments or activities (the tabs) would be stronger coupled.

How to setResult() for a TabActivity which contains activity for tabs

My TabActivity contains two tabs which calls two two different activities . I want to setResult() for the TabActivity when either one of the child finishes.
Is there any method to find out when my activity inside tab finishes ?
Thank you
-Eby
I found another way
` #Override
public void finishFromChild(Activity child)
{
setResult(REFRESH);
super.finishFromChild(child);
}
`
finsihFromChild will let us know when the child activity is finishing!!
#pentium10 thank you very much for your suggestion..
Ok i've got an even easier method to pass the result:
in your child activity do this
Intent list = this.getIntent();
list.setAction(Integer.toString(RESULT_CODE_TO_PASS));
finish();
and then in the parent do this:
#Override
public void finishFromChild(Activity child) {
Intent test = child.getIntent();
setResult(new Integer(test.getAction()));
super.finishFromChild(child);
}
You need to issue a Broadcast from your child activity(when finished) and implement the BroadcastReceiver on the class you want to catch the broadcast. You can use the extras to transfer data from one activity to another.

Categories

Resources