Saving and restoring an EditText cursor position in a Dialog dialog using savedInstanceState

Most of what you read says that you should call onSaveInstanceState()on DialogFragmentto save its state, and then call onActivityCreated()and restore it there. Although this works, I found a problem:

If I have EditTextin my custom layout my DialogFragment AlertDialogand lets say that I enter my password. The password is masked and the cursor blinks after entering the last password. If I save the value entered in EditTextin onSaveInstanceState()and restore the state with onActivityCreated(), it will be restored, but the cursor moves to the beginning of what I just printed before the rotation, instead of remaining at the end.

However, if I restored what I saved using onCreateDialog(), first checking mine savedInstanceStatefor null, then my cursor will remain at the end after the last character typed in which it should be.

I wonder which path is correct, although I can see that both work fine and save the password when the rotation changes. The only thing that few people think is that the cursor moves to the beginning instead of remaining at the end in the case onActivityCreated().

+4
source share
1 answer

The EditText widget automatically saves and restores its own state. You do not need to save and restore the entered string. Let the widget handle its own state and the cursor position will not change after a restart.

Here is an example:

public class PasswordDialog extends DialogFragment {
    private static final String TAG = "PasswordDialog";
    private static final String TITLE_KEY = "title";
    private String mTitle;

    public static PasswordDialog newInstance(String title) {
        PasswordDialog f = new PasswordDialog();
        Bundle args = new Bundle();
        args.putString(TITLE_KEY, title);
        f.setArguments(args);
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState==null) {
            //not restart
            Bundle args = getArguments();
            if (args==null) {
                throw new IllegalArgumentException("Bundle args required");
            }
            mTitle = args.getString(TITLE_KEY);
        } else {
            //restart
            mTitle = savedInstanceState.getString(TITLE_KEY);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(TITLE_KEY, mTitle);
    }

    @Override
    @NonNull
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Log.i(TAG, "onCreateDialog()");

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

        LayoutInflater inflater = getActivity().getLayoutInflater();
        View customView = inflater.inflate(R.layout.fragment_dialog_note_edit, null);

        final EditText passwordView = (EditText) customView.findViewById(R.id.dialog_note_edit_text);

        builder
                .setTitle(mTitle)
                .setView(customView)
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        //nothing
                    }
                })
                .setPositiveButton("Save", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        String password = passwordView.getText().toString();
                        Log.i(TAG, "password= " + password);
                    }
                });

        return builder.create();
    }
}
+5
source

All Articles