What is the proper way to handle orientation change when a custom alertdialog has an open spinner?

前端 未结 3 1079
星月不相逢
星月不相逢 2021-01-05 13:42

In my app I have a custom AlertDialog (handled by the system using showDialog()) which contains a tabhost with 2 tabs. In one of the tabs is a spinner. I can rotate my scr

相关标签:
3条回答
  • 2021-01-05 14:25

    Ok, I think I've found your problem: dialog.dismiss();
    You are doing really strange thing - you are creating dialog through activity but say dismiss to it not to activity to dismiss it - those are two different approaches which you can't mix. You should choose one method: dialog.show and dialog.dismiss or activity.showDialog() and activity.dismissDialog() <- this is better because handles orientation change.
    What you should do is just remove dialog from class variables, use activity.showDialog everywhere. Probably your problem was in dismissing dialog in onClick. Just use YourActivityName.this.dismissDialog(DIALOG_NUMBER) and it should work.
    Read more about dialogs form developers site - I had also such problems and taken long time to learn how it works but after all - dialogs are not so complicated ;)

    0 讨论(0)
  • 2021-01-05 14:25

    I had a similar a crash. I worked around by disabling orientation changes when dialog is displayed.

    @Override
    public void onDismiss(DialogInterface dialog) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }
    
    @Override
    public void onShow(DialogInterface dialog) {
        int loadedOrientation = getResources().getConfiguration().orientation;
        int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
        if (loadedOrientation == Configuration.ORIENTATION_LANDSCAPE) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        } else if (loadedOrientation == Configuration.ORIENTATION_PORTRAIT) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }
        setRequestedOrientation(requestedOrientation);
    }
    

    NOTE: I actually found that there is no reliable way to lock screen orientation.

    0 讨论(0)
  • 2021-01-05 14:31

    I found a better solution. It is actually not so hard to replace Spinner with a button that looks and behaves like Spinner (except the crash, fortunately).

    <Button 
         android:background="@android:drawable/btn_dropdown" 
         android:gravity="left|center_vertical"
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" />
    

    public void showSpinner() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setTitle(_spinnerPrompt);
        builder.setSingleChoiceItems(_spinnerOptions, _spinnerSelection,
          new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int item) {
                _spinnerSelection = item;
                _pseudoSpinner.setText(_spinnerOptions[item]);
                _restoreSpinnerOnRestart = false;
                dialog.dismiss();
            }
        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                _restoreSpinnerOnRestart = false;
            }
        });
        AlertDialog alert = builder.create();
        _restoreSpinnerOnRestart = true;
        alert.show();
        }
    
    @Override
    public Bundle onSaveInstanceState() {
        Bundle state = super.onSaveInstanceState();
        state.putBoolean(STATE_SPINNER_RESTORE, _restoreSpinnerOnRestart);
        state.putInt(STATE_SPINNER_SELECTION, _spinnerSelection);
        return state;
    };
    
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        _spinnerSelection = savedInstanceState.getInt(STATE_SPINNER_SELECTION, -1);
        _restoreSpinnerOnRestart = savedInstanceState.getBoolean(STATE_SPINNER_RESTORE);
        _pseudoSpinner.setText(_spinnerOptions[_spinnerSelection]);
    
        if (_restoreSpinnerOnRestart) {
            showSpinner();
        }
    };
    
    0 讨论(0)
提交回复
热议问题