Question

I gave android:singleLine="true" option on EditTextPreference, and when the edit box in the dialog has the focus, the software keyboard shows "Done" button in place of Enter key. However if I press the done button, only the software keyboard closes, and I still have to click Done button on the dialog.

Is there anyway to make enter key and ime action key on the software keyboard to close the dialog and apply the new value?

Was it helpful?

Solution

First, I set the IME Option to IME_ACTION_DONE

mEditTextPreference.getEditText().setImeOptions(EditorInfo.IME_ACTION_DONE);

and then using following code to save value and close dialog.

mEditTextPreference.getEditText().setOnEditorActionListener(new OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE){
            //mEditTextPreference.setText(mEditTextPreference.getEditText().getText().toString());

            //better solution
            mEditTextPreference.onClick(mEditTextPreference.getDialog(), Dialog.BUTTON_POSITIVE);
            mEditTextPreference.getDialog().dismiss();
            return true;
        }
        return false;
    }
});

OTHER TIPS

Have you tried using android:inputType="textCapSentences" (textCapSentences is one of many options) in the XML for the edit text. I had a similar problem and that was able to solve it also gave me control of what keyboard I could show.

For instance if I had a number only field I could use android:inputType="number" which would show the number pad vs the qwerty keyboard first, there are many different options

I think that DialogPreference with EditText should normally always close itself when user presses Done button and soft keyboard closes. To make this behavior by default it's easy to implement a customized EditTextPreferenceCustomized and then use it everywhere instead of standard EditTextPreference.

import android.app.Dialog;
import android.content.Context;
import android.preference.EditTextPreference;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

public class EditTextPreferenceCustomized extends EditTextPreference
{
    public EditTextPreferenceCustomized(Context context)
    {
        super(context);
    }

    public EditTextPreferenceCustomized(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public EditTextPreferenceCustomized(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onAddEditTextToDialogView(View dialogView, EditText editText)
    {
        super.onAddEditTextToDialogView(dialogView, editText);

        // editText.setImeOptions(EditorInfo.IME_ACTION_DONE); - uncomment if it's not specified in preferences.xml

        editText.setOnEditorActionListener(new OnEditorActionListener()
        {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
            {
              if(actionId == EditorInfo.IME_ACTION_DONE)
              {
                onClick(getDialog(), Dialog.BUTTON_POSITIVE);
                getDialog().dismiss();
                return true;
              }
              return false;
            }
        });
    }
}

The code is partially based on the helpful solution from @LZN, but this will eliminate the need for setting action listener for every preference in java code. Just replace in preferences.xml all instances of EditTextPreference to com.yourpackage.EditTextPreferenceCustomized.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top