Après la mise à jour vers le dernier référentiel de support,
compile 'com.Android.support:appcompat-v7:24.2.0'
compile 'com.Android.support:design:24.2.0'
compile 'com.Android.support:percent:24.2.0'
compile 'com.Android.support:recyclerview-v7:24.2.0'
Je reçois une exception bizarre.
Java.lang.IllegalStateException: Fragment null must be a public static class to be properly recreated from instance state.
at Android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.Java:435)
at Android.support.v4.app.BackStackRecord.add(BackStackRecord.Java:414)
at Android.support.v4.app.DialogFragment.show(DialogFragment.Java:154)
at com.androidapp.base.BaseActivity.showDialogFragment(BaseActivity.Java:78)
at com.androidapp.MainActivity.showNewDialog(MainActivity.Java:304)
at com.androidapp.MainActivity$6.onClick(MainActivity.Java:228)
Dans mon BaseActivity class, j'ai créé un fragment réutilisable pouvant être utilisé dans une classe d'activité qui étend le BaseActivty
public void showDialogFragment(DialogFragment newFragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack("dialog");
newFragment.show(ft, "dialog");
}
Retour à la MainActivty J'ai utilisé le fragment comme ça,
public class MainActivity extends BaseActivity {
@SuppressLint("ValidFragment")
public void showNewDialog(int type, String title, String message) {
final DialogNew dialog = new DialogNew() {
@Override
public void success(boolean isLandscape) {
.......
}
@Override
public void cancel() {
}
};
dialog.setArgs(title, message);
super.showDialogFragment(dialog);
}
}
Le DialogNew class est ci-dessous,
public abstract class DialogNew extends DialogFragment {
private View rootView;
private String title;
private String message;
public void setArgs(String title, String message) {
Bundle args = new Bundle();
args.putString("title", title);
args.putString("message", message);
setArguments(args);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_TITLE, 0);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_new_dialog, container, false);
init();
setListeners();
return rootView;
}
public abstract void success(boolean isLandscape);
public abstract void cancel();
}
PS: Le même code fonctionne avec un référentiel de support plus ancien.
L'erreur n'est pas particulièrement étrange. Si vous n'aviez pas eu cette erreur auparavant, ça était bizarre.
Android détruit et recrée des fragments dans le cadre d'un changement de configuration (par exemple, la rotation d'écran) et dans le cadre de la reconstruction d'une tâche si nécessaire (par exemple, l'utilisateur bascule vers une autre application. tente de revenir à votre application, le tout dans un délai de 30 minutes environ). Android n'a aucun moyen de recréer une sous-classe anonyme de DialogNew
.
Créez donc une classe Java public
régulière (ou une classe public
static
imbriquée) qui étend DialogNew
et contient votre logique métier, en remplacement de la sous-classe anonyme DialogNew
que vous utilisez actuellement.
Edit: Vous ne voulez probablement pas faire ça ... Voir les commentaires.
L'exemple de code ressemble à ce que j'avais suggéré sur ici et j'ai récemment découvert que la solution que j'avais là-bas ne fonctionnait plus. J'ai mis à jour ma réponse à Java7, mais si vous avez Java8, la solution est très simple:
(Je n'ai pas encore testé cela)
public class DialogNew extends DialogFragment {
private View rootView;
private String title;
private String message;
// Do nothing by default
private Consumer mSuccess = (boolean b) -> {};
private Runnable mCancel = () -> {};
public void setArgs(String title, String message) {
Bundle args = new Bundle();
args.putString("title", title);
args.putString("message", message);
setArguments(args);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_TITLE, 0);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_new_dialog, container, false);
// use mSuccess.accept(boolean) when needed
init();
setListeners();
return rootView;
}
public void setSuccess(Consumer success) {
mSuccess = success;
}
public void setCancel(Runnable cancel) {
mCancel = cancel;
}
}
Puis dans l'activité principale:
public class MainActivity extends BaseActivity {
public void showNewDialog(int type, String title, String message) {
final DialogNew dialog = new DialogNew();
dialog.setArgs(title, message);
dialog.setSuccess((boolean isLandscape) -> {
//....
});
super.showDialogFragment(dialog);
}
}