问题
I have this scenario implemented where I have a navigation drawer with nested fragments that are added to the back stack with tag. Every fragment has the following implemented:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_feed, container,
false);
// Doing initialisaion here
} else {
((ViewGroup) rootView.getParent()).removeView(rootView);
}
return rootView;
This was the best way I could think to maintain my lists inside these fragments and their dynamic headers and footers (Thinking about implementing a new approach here already).
Furthermore I have these broadcasts when a user loges out of my app so that I refresh these lists, or when the location changes:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
locationBroadcastReciever,
new IntentFilter(UpdateLocationIntentService.LOCATION_CHANGED));
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
significantBroadcastReciever,
new IntentFilter(UserDefaultsManager.SIGNIFICANT_CHANGED));
// Further code here
}
The on detach is called when the fragment is detached:
@Override
public void onDetach() {
super.onDetach();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(
locationBroadcastReciever);
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(
significantBroadcastReciever);
// This is also where I cancel any pending request for fetching data
};
This way is right now working but I have to check when a request is finished whether some of the views have been destroyed because onDestroyView is called when I replace the fragment with another but onDetach is not called since the fragment is on back stack and its not detached yet.
The current implementation with view nullpointer checks is allowing me to update 4 fragments simultaneously when a user is logged out (or logged in) or location changed and there were no items previously on the list.
I am sure that there is a better way, but I cannot seem to get the same results at what ever else I try.
回答1:
My case was to update the textfield in one of the fragments hosted by MainActivity.The simplest solution I found was this:--
In my MainActivity class retrieved the running instance of MainActivtiy.This is my MAinActivity
private static MainActivity mainActivityRunningInstance;
public static MainActivity getInstace(){
return mainActivityRunningInstance;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainActivityRunningInstance =this;
----------
}
Now in Broadcast reciever's onRecieve method, get that instance and call the update method
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches(Intents.PROVIDER_CHANGED_ACTION)) {
String textValue="the text field value";
// the null check is for, if the activity is not running or in paused state, in my case the update was required onlyif the main activity is active or paused
if(MainActivity.getInstace()!=null)
MainActivity.getInstace().updateUI(textValue);
}
Now for the part where we need to run the update in UIThread,The updateUI method of MainActivity will call the fragments update method.
public void updateUI(final String str) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
//use findFragmentById for fragments defined in XML ((SimpleFragment)getSupportFragmentManager().findFragmentByTag(fragmentTag)).updateUI(str);
}
});
}
and the final step is updating the fragment's text field
public void updateUI(String str){
tv_content.setText(str);
}
and Bingo, its done. I referred post to solve my issue. Hope it help others.
来源:https://stackoverflow.com/questions/26615936/broadcast-receivers-and-fragments