[android] Android에서 화면 회전시 대화 상자 닫기 방지

활동이 다시 시작될 때 경고 빌더로 빌드 된 대화 상자가 닫히지 않도록 방지하려고합니다.

onConfigurationChanged 메서드를 오버로드하면 성공적으로이 작업을 수행하고 레이아웃을 올바른 방향으로 재설정 할 수 있지만 edittext의 고정 텍스트 기능이 손실됩니다. 그래서 대화 문제를 해결하면서이 edittext 문제를 만들었습니다.

편집 텍스트에서 문자열을 저장하고 onCofiguration 변경에서 다시 할당하면 여전히 회전 전에 입력 한 값이 아닌 초기 값으로 기본 설정되는 것처럼 보입니다. 강제로 무효화하더라도 업데이트하는 것 같습니다.

대화 문제 나 edittext 문제를 해결해야합니다.

도와 주셔서 감사합니다.



답변

요즘이 문제를 피하는 가장 좋은 방법은 DialogFragment.

확장하는 새 클래스를 만듭니다 DialogFragment. 재정 onCreateDialog오래된 당신의 반환 Dialog또는를 AlertDialog.

그런 다음 DialogFragment.show(fragmentManager, tag).

다음은 다음과 같은 예입니다 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();
    }
}

그리고 당신이 부르는 활동에서 :

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

이 답변은 다음 세 가지 질문 (및 답변)을 설명하는 데 도움이됩니다.


답변

// Prevent dialog dismiss when orientation changes
private static void doKeepDialog(Dialog dialog){
    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
    lp.copyFrom(dialog.getWindow().getAttributes());
    lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
    lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
    dialog.getWindow().setAttributes(lp);
}
public static void doLogout(final Context context){
        final AlertDialog dialog = new AlertDialog.Builder(context)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setTitle(R.string.titlelogout)
        .setMessage(R.string.logoutconfirm)
        .setPositiveButton("Yes", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ...
            }

        })
        .setNegativeButton("No", null)
        .show();

        doKeepDialog(dialog);
    }


답변

방향 변경시 레이아웃을 변경하는 경우 android:configChanges="orientation" 어쨌든 뷰를 다시 생성하기 때문에 매니페스트에 입니다.

다음 방법을 사용하여 활동의 현재 상태 (입력 한 텍스트, 표시된 대화 상자, 표시된 데이터 등)를 저장합니다.

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
}

이렇게하면 활동이 다시 onCreate를 거치고 나중에 EditText 값을 다시 설정할 수있는 onRestoreInstanceState 메서드를 호출합니다.

더 복잡한 객체를 저장하려면 다음을 사용할 수 있습니다.

@Override
public Object onRetainNonConfigurationInstance() {
}

여기에 모든 객체를 저장할 수 있으며 onCreate에서 객체 getLastNonConfigurationInstance();를 가져 오기 위해 호출 해야합니다.


답변

AndroidManifest.xml의 활동 요소와 함께 android : configChanges = “orientation”을 추가하기 만하면됩니다.

예:

<activity
            android:name=".YourActivity"
            android:configChanges="orientation"
            android:label="@string/app_name"></activity>


답변

매우 쉬운 방법은 메서드에서 대화 상자를 만드는 것입니다 onCreateDialog()(아래 참고 참조). 을 통해 보여줍니다 showDialog(). 이 방법은, 안드로이드는 당신을위한 회전을 처리하고 당신이 호출 할 필요가 없습니다 dismiss()onPause()WindowLeak를 방지하고 다음 대화 상자를 복원 할 수없는 둘 수 있습니다. 문서에서 :

이 활동에서 관리하는 대화 상자를 표시합니다. onCreateDialog (int, Bundle)에 대한 호출은 주어진 ID에 대해 처음 호출 될 때 동일한 ID로 이루어집니다. 이후부터 대화 상자가 자동으로 저장되고 복원됩니다.

자세한 내용은 Android 문서 showDialog () 를 참조하세요. 누군가에게 도움이되기를 바랍니다!

참고 : AlertDialog.Builder를 사용하는 경우 show()에서 onCreateDialog()호출 create()하지 말고 대신 호출하십시오 . ProgressDialog를 사용하는 경우 개체를 만들고 필요한 매개 변수를 설정 한 다음 반환하면됩니다. 결론적으로 show()내부에서 onCreateDialog()문제 가 발생하면 Dialog 인스턴스를 생성하고 반환하면됩니다. 작동합니다! (onCreate ()에서 showDialog ()를 사용하여 문제가 발생했습니다-실제로 대화 상자를 표시하지 않지만 onResume () 또는 리스너 콜백에서 사용하면 잘 작동합니다).


답변

이 질문은 오래 전에 답변되었습니다.

그러나이는 비 해키간단한 자신을 위해 솔루션 I 사용은.

이 도우미 클래스 를 직접 만들었 으므로 응용 프로그램에서도 사용할 수 있습니다.

사용법은 다음과 같습니다.

PersistentDialogFragment.newInstance(
        getBaseContext(),
        RC_REQUEST_CODE,
        R.string.message_text,
        R.string.positive_btn_text,
        R.string.negative_btn_text)
        .show(getSupportFragmentManager(), PersistentDialogFragment.TAG);

또는

 PersistentDialogFragment.newInstance(
        getBaseContext(),
        RC_EXPLAIN_LOCATION,
        "Dialog title",
        "Dialog Message",
        "Positive Button",
        "Negative Button",
        false)
    .show(getSupportFragmentManager(), PersistentDialogFragment.TAG);





public class ExampleActivity extends Activity implements PersistentDialogListener{

        @Override
        void onDialogPositiveClicked(int requestCode) {
                switch(requestCode) {
                  case RC_REQUEST_CODE:
                  break;
                }
        }

        @Override
        void onDialogNegativeClicked(int requestCode) {
                switch(requestCode) {
                  case RC_REQUEST_CODE:
                  break;
                }
        }
}


답변

대화 상자의 onSave / onRestore 메서드를 활동의 onSave / onRestore 메서드 와 결합하여 대화 상자의 상태를 유지할 수 있습니다.

참고 : 이 방법은 경고 메시지 표시와 같은 “단순”대화 상자에서 작동합니다. 대화 상자에 포함 된 WebView의 내용을 재현하지 않습니다. 회전하는 동안 복잡한 대화가 사라지는 것을 정말로 막으려면 Chung IW의 방법을 시도하십시오.

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
     myDialog.onRestoreInstanceState(savedInstanceState.getBundle("DIALOG"));
     // Put your codes to retrieve the EditText contents and 
     // assign them to the EditText here.
}

@Override
protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     // Put your codes to save the EditText contents and put them 
     // to the outState Bundle here.
     outState.putBundle("DIALOG", myDialog.onSaveInstanceState());
}