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.
Related
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
I have a Fragment with a ListView and a BroadcastReceiver that updates the ListView when new data arrives. The Fragments life is controlled by a ViewPager.
In regard to where to (un)register the BroadcastReceiver, I found several places suggesting to do it in
onResume():
refreshReceiver = new RefreshReceiver();
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
refreshReceiver,
refreshIntentFilter);
onPause():
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(refreshReceiver);
However, this does not work properly. When I long-press the home button to get to the Recent apps screen, onPause() is called. When new information comes in while I'm on Recent apps, the ListView misses the update and shows old information after I go back there.
Now I was thinking about moving the unregistering to the onStop() method (or even in onDestroy()), but is that guaranteed to be called when the fragment is destroyed? I was worried because if the BroadcastManager holds a reference to the BroadcastReceiver and that in turn holds a reference to the Fragment, it would be quite a serious memory leak.
if you don't need receiver, then unregister it. if you use it only in that fragment, you may consider unregistering it onViewDestroyed().
According this answer , if your fragment is single and not in pager you can un/register LBM in :
#Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
broadcast_manager, new IntentFilter("filter"));
}
#Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(broadcast_manager);
}
Else you need to find out when fragment is visible then register LBM.
through this:
public class MyFragment extends Fragment {
#Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (visible) {
// Register LBM
}
}
// ...
}
you can register LBM in fragment
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
I have an activity with two fragments, with only 1 of the two fragments being displayed at a given time, as determined by the user. Both fragments subscribe to data via a broadcast receiver.
The acitivty manages which fragment is displayed using the fragment manager's replace() method, e.g.
getFragmentManager().beginTransaction().replace(R.id.north_fragment, fragment1, FRAGMENT_TAG).commit();
The Broadcast Receivers are registered in the Fragment's onCreateView() override: The broadcast receiver receives the appropriate data as expected.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_spectrum_analyzer_graph, container, false);
setupGraphView(rootView);
// register for Spectrum Frame Response messages
myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive()");
// do stuff
}
}
The broadcast receiver is unregistered in onDestroyView(), e.g.:
#Override
public void onDestroyView() {
super.onDestroyView();
getActivity().unregisterReceiver(m_spectrumDataFrameReceiver);
}
Is there a way I can keep the fragment receiving data through the BroadcastReceiver, even when it's not visible (after it's been destroyed)? I want the receiver to continue getting data and storing it in the Fragment, even if the fragment is not visible (but the activity is visible), but I know that I need to unregister the broadcast receiver at some point.
Should unregistration be done when the Activity is destroyed (calling in to its activities to unregister), or is it too late here? I'm fairly new to the intricacies of Fragment lifecyle, and am not quite sure what to do.
Instead of replacing each fragment everytime just use the add method fragment transaction so it is still alive when invisible.
solution:
replace the replace use the add
beginTransaction().add(R.id.north_fragment, fragment1, FRAGMENT_TAG).commit();
You should register your receiver in activity onResume and unregister it in onPause. You receiver will receive broadcast as long as activity is running. Then you can pass received data to respective fragment by any means.
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.