Prevent Dialog Dismissal on Screen Rotation in Android

Prevent dialog dismissal on screen rotation in Android

The best way to avoid this problem nowadays is by using a DialogFragment.

Create a new class which extends DialogFragment. Override onCreateDialog and return your old Dialog or an AlertDialog.

Then you can show it with DialogFragment.show(fragmentManager, tag).

Here's an example with a Listener:

public class MyDialogFragment extends DialogFragment {

public interface YesNoListener {
void onYes();

void onNo();
}

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof YesNoListener)) {
throw new ClassCastException(activity.toString() + " must implement YesNoListener");
}
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.dialog_my_title)
.setMessage(R.string.dialog_my_message)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onYes();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
((YesNoListener) getActivity()).onNo();
}
})
.create();
}
}

And in the Activity you call:

new MyDialogFragment().show(getSupportFragmentManager(), "tag"); // or getFragmentManager() in API 11+

This answer helps explain these other three questions (and their answers):

  • Android Best way of avoid Dialogs to dismiss after a device rotation
  • Android DialogFragment vs Dialog
  • How can I show a DialogFragment using compatibility package?

Prevent a ProgressDialog from being dismissed on rotation but still allow dismissal from AsyncTask

Thanks Selvin, your code and comment pointed me into the correct direction.

The problem is that I have to freshly fetch the Fragment when I dismiss it. Additionally, since the Activity might not be active when the dialog is dismissed I need to allow stateloss when I dismiss it to avoid a NullPointerException. Thus, I update the AsyncTask to the following and it works fine.

        // Run a background task and show a dialog
new AsyncTask<Void, Void, Void>() {
@Override
protected void onPreExecute() {
// show progress dialog
MyDialogFragment ft = MyDialogFragment.newInstance();
ft.show(getActivity().getFragmentManager(), "dialog");
}

@Override
protected Void doInBackground(Void...params) {
try {
// Do some work...
Thread.sleep(5000);
} catch (InterruptedException ignored) {}

return null;
}

@Override
protected void onPostExecute(Void p) {
MyDialogFragment ft =
(MyDialogFragment) getFragmentManager()
.findFragmentByTag("dialog");

// remove progress dialog
ft.dismissAllowingStateloss();
}
}.execute();

Again thanks for your help.

Android - Best way of avoiding Dialogs to dismiss after a device rotation

You should now use DialogFragment from new Fragments API. To use it on the platform lower, than 3.0, use compatibility package.

How to prevent ProgressDialog to dismissing on screen rotation change in Android?

I end up to use DialogFragment and it works.

public class MainActivity extends Activity{



public void prepareViews(int ID, boolean state){
switch(ID){
case USERNAME_TEXTBOX:
LoginUsernameTextBox.setEnabled(state);
break;
case PASSWORD_TEXTBOX:
LoginPasswordTextBox.setEnabled(state);
break;
case LOGIN_BUTTON:
LoginButton.setEnabled(state);
break;
case LOGIN_PROGRESSBAR:
if(state == true){
LoginProgressBar.setVisibility(View.VISIBLE);
LoginProgressBar.setIndeterminate(true); }
else{
LoginProgressBar.setVisibility(View.GONE);
}
break;
case CONNECTING_DIALOG:
if(state == true){
showDialog();
}
break;
}
}

public void showDialog() {
FragmentManager fragmentManager = getFragmentManager();
ProgressDialogFragment newFragment = new ProgressDialogFragment();
newFragment.show(fragmentManager, "Dialog");
}

public static class ProgressDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "", "Connecting to "
+ DeviceName.subSequence(0, DeviceName.length() - 17));
return progressDialog;
}
}
}

How to use DialogFragments to save the dialog box while screen rotation when I'm using function for alertDialog?

You just need to create a DialogFragment class, create an AlertDialog, and do everything you're doing now on your AlertDialog. You can send the String in the constructor. Then, you can call back into the Activity for the click events.

Something like this for the DialogFragment (this goes in it's own Java file):

import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;

public class GameDialogFragment extends DialogFragment {

String s;

public GameDialogFragment(String str) {
this.s = str;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String title = "";
String message = "";

if(s.equals("You") || (s.contains("P")))
title = "Congratulations...";
else
title = "Game's Up...";

if(s.equals("You") || s.contains("P"))
message = s+" Win The Game...";
else
message = "You Lose... I Win...";

final ImageView img = new ImageView(getActivity());
if(s.equals("You") || (s.contains("P")))
img.setImageResource(R.drawable.firecrackers);
else
img.setImageResource(R.drawable.mmm);

AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());

alertBuilder.setView(img);


AlertDialog dialog = builder.setTitle(title)
.setMessage(message)
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
((MainActivity2) getActivity()).clickedYes();
}
})
.setNegativeButton("Main Menu", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
((MainActivity2) getActivity()).clickedNo();
}
})
.create();

return dialog;
}
}

Then, in the Activity, show the DialogFragment in your alertShow() method, and define the click handlers:

public void alertShow(String s){
new GameDialogFragment(s).show(getFragmentManager(), "");
}

public void clickedYes() {
SessionClass sessionClass = (SessionClass)getApplicationContext();
String str = sessionClass.getPlayer();
Intent i;
if(null != str && str.contains("2")){
i = new Intent(MainActivity2.this, Game1_1.class);
startActivity(i);
}
}

public void clickedNo() {
Intent intent = new Intent(MainActivity2.this, MainActivity2.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}

Android how to prevent screen rotation for specific dialog fragment

Set the below tags in DialogFragment class where you want to lock screen rotation

@Override public void onResume() {
super.onResume();
//lock screen to portrait
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

@Override public void onPause() {
super.onPause();
//set rotation to sensor dependent
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
}


Related Topics



Leave a reply



Submit