EDYCJA: Nie jest to błąd, ale raczej wada we frameworku fragmentów. Lepszą odpowiedzią na to pytanie jest ta, której udzielił powyżej @Arcao.
---- Oryginalny post ----
Właściwie jest to znany błąd w pakiecie wsparcia (edycja: właściwie nie jest to błąd. Zobacz komentarz @ alex-lockwood). Opublikowane obejście w komentarzach do zgłoszenia błędu polega na zmodyfikowaniu źródła DialogFragment w następujący sposób:
public int show(FragmentTransaction transaction, String tag) {
return show(transaction, tag, false);
}
public int show(FragmentTransaction transaction, String tag, boolean allowStateLoss) {
transaction.add(this, tag);
mRemoved = false;
mBackStackId = allowStateLoss ? transaction.commitAllowingStateLoss() : transaction.commit();
return mBackStackId;
}
Zauważ, że to gigantyczny hack. Sposób, w jaki to zrobiłem, polegał na stworzeniu własnego fragmentu okna dialogowego, w którym mogłem się zarejestrować z oryginalnego fragmentu. Kiedy ten inny fragment dialogu zrobił coś (na przykład został odrzucony), powiedział wszystkim słuchaczom, że odchodzi. Zrobiłem to tak:
public static class PlayerPasswordFragment extends DialogFragment{
Player toJoin;
EditText passwordEdit;
Button okButton;
PlayerListFragment playerListFragment = null;
public void onCreate(Bundle icicle){
super.onCreate(icicle);
toJoin = Player.unbundle(getArguments());
Log.d(TAG, "Player id in PasswordFragment: " + toJoin.getId());
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle){
View v = inflater.inflate(R.layout.player_password, container, false);
passwordEdit = (EditText)v.findViewById(R.id.player_password_edit);
okButton = (Button)v.findViewById(R.id.ok_button);
okButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
passwordEntered();
}
});
getDialog().setTitle(R.string.password_required);
return v;
}
public void passwordEntered(){
playerListFragment.joinPlayer(toJoin, passwordEdit.getText().toString());
dismiss();
}
public void registerPasswordEnteredListener(PlayerListFragment playerListFragment){
this.playerListFragment = playerListFragment;
}
public void unregisterPasswordEnteredListener(){
this.playerListFragment = null;
}
}
Teraz mam sposób powiadamiania PlayerListFragment, gdy coś się wydarzy. Zauważ, że bardzo ważne jest, abyś odpowiednio wywołał unregisterPasswordEnteredListener (w powyższym przypadku, gdy PlayerListFragment "znika"), w przeciwnym razie ten fragment okna dialogowego może próbować wywołać funkcje zarejestrowanego nasłuchiwania, gdy ten odbiornik już nie istnieje.
onResumeFragments()
nie istnieje wActivity
klasie. Jeśli używasz wersji podstawowejActivity
, powinieneś użyćonPostResume()
zamiast niej.