РЕДАКТИРОВАТЬ: Не ошибка, а скорее недостаток в структуре фрагментов. Лучшим ответом на этот вопрос является ответ, предоставленный @Arcao выше.
---- Исходный пост ----
На самом деле это известная ошибка в пакете поддержки (редактировать: на самом деле это не ошибка. см. комментарий @alex-lockwood). Обходной путь, опубликованный в комментариях к отчету об ошибке, заключается в изменении источника DialogFragment следующим образом:
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;
}
Обратите внимание, что это гигантский взлом. То, как я на самом деле это сделал, это просто создать свой собственный фрагмент диалога, который я мог зарегистрировать из исходного фрагмента. Когда этот другой фрагмент диалога делал что-то (например, закрывался), он сообщал всем слушателям, что он уходит. Я сделал это так:
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(){
//TODO handle if they didn't type anything in
playerListFragment.joinPlayer(toJoin, passwordEdit.getText().toString());
dismiss();
}
public void registerPasswordEnteredListener(PlayerListFragment playerListFragment){
this.playerListFragment = playerListFragment;
}
public void unregisterPasswordEnteredListener(){
this.playerListFragment = null;
}
}
Так что теперь у меня есть способ уведомлять PlayerListFragment, когда что-то происходит. Обратите внимание, что очень важно, чтобы вы вызывали unregisterPasswordEnteredListener соответствующим образом (в приведенном выше случае, когда когда-либо PlayerListFragment «уходит»), иначе этот фрагмент диалога может попытаться вызвать функции для зарегистрированного слушателя, когда этот слушатель больше не существует.
person
Kurtis Nusbaum
schedule
11.04.2012