Setting EditText imeOptions to actionNext has no e

2019-04-24 12:25发布

问题:

Here my edittext:-

    <com.os.fastlap.util.customclass.EditTextPlayRegular
                    android:id="@+id/full_name_et"
                    style="@style/Edittext_white_13sp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_5sdp"
                    android:background="#00ffffff"
                    android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    android:imeOptions="actionNext"
                    android:inputType="text"
                    android:maxLength="20"
                    android:maxLines="1"
                    android:nextFocusDown="@+id/last_name_et"
                    android:textCursorDrawable="@null" /> 

When I remove digit in edittext it work fine but with digit imeOptions doesn't work. But one surprising thing if I use singleLine instead of maxLines it work fine. But singleLine now is deprecated. I cannot remove digit in my edittext and I don't want use deprecated method. Any one can solve this problem. Thanks in adavance

回答1:

Here is a simplified solution with the software keyboard button "Next":

final String NOT_ALLOWED_CHARS = "[^a-zA-Z0-9]+";

final EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {}

        @Override
        public void afterTextChanged(Editable s) {
            if (!TextUtils.isEmpty(s)) {
                // remove the listener to avoid StackoverflowException
                editText.removeTextChangedListener(this);
                // replace not allowed characters with empty strings
                editText.setText(s.toString().replaceAll(NOT_ALLOWED_CHARS, ""));
                // setting selection moves the cursor at the end of string
                editText.setSelection(editText.getText().length());
                // add the listener to keep watching
                editText.addTextChangedListener(this);
            }
        }
    });

Here the regular expression [^a-zA-Z0-9]+ corresponds to the allowed values of android:digits of the EditText in question.



回答2:

you can use

 android:lines="1"

in place of

android:maxLines 

or

android:singleLine="true".

I know you have tried many solutions, Try with

android:lines="1"

these if you haven't tried earlier.



回答3:

The problem is you are clicking on Enter key instead of the actionNext you need in order to move cursor to next EditText

Specify the Input Method Action

Most soft input methods provide a user action button in the bottom corner that's appropriate for the current text field. By default, the system uses this button for either a Next or Done action unless your text field allows multi-line text (such as with android:inputType="textMultiLine"), in which case the action button is a carriage return. However, you can specify additional actions that might be more appropriate for your text field, such as Send or Go.

It causes carriage return for your action button. So it means that doesn't fire android:nextFocusDown

First of all, lets see what is difference between singleLine which is deprecated and maxLines

singleLine

When you set android:singleLine="true" one line text is in EditText visible but Enter key isn't visible in keypad

maxLines

when you set android:maxLines attribute with the particular value only same amount of line text is visible in EditText and enter key in keypad also visible for Entering.

So When you click action button it is firing Enter Action according to your code. Also you must change your inputType attribute with android:inputType="textMultiLine" if you use android:maxLines attribute

maxLines

added in API level 1 int maxLines Makes the TextView be at most this many lines tall. When used on an editable text, the inputType attribute's value must be combined with the textMultiLine flag for the maxLines attribute to apply.

May be an integer value, such as "100".


When I customized your code with the correct attributes still it was firing Enter key instead of IME_ACTION_NEXT which you want. I think it didn't solve the problem due to

textMultiLine Can be combined with text and its variations to allow multiple lines of text in the field. If this flag is not set, the text field will be constrained to a single line. Corresponds to TYPE_TEXT_FLAG_MULTI_LINE.


TYPE_TEXT_FLAG_MULTI_LINE

added in API level 3 int TYPE_TEXT_FLAG_MULTI_LINE Flag for TYPE_CLASS_TEXT: multiple lines of text can be entered into the field. If this flag is not set, the text field will be constrained to a single line. The IME may also choose not to display an enter key when this flag is not set, as there should be no need to create new lines.

Constant Value: 131072 (0x00020000)


SOLUTION:

Subclass EditText and adjust the IME options. After that you don't need android:maxLines or android:singleLine attributes.

@Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnection connection = super.onCreateInputConnection(outAttrs);
        int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
        if ((imeActions&EditorInfo.IME_ACTION_NEXT) != 0) {
            // clear the existing action
            outAttrs.imeOptions ^= imeActions;
            // set the DONE action
            outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
        }
        if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
            outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        }
        return connection;
    }

You could also check another post here. I reconfigured the accepted answer of this post on your purpose



回答4:

android:digits specifies that the EditText has a numeric input method, as per the docs

You could use android:inputType="personName" to achieve the same as your current digits attr



回答5:

android:maxLines only Makes the TextView be at most this many lines tall, not prevent user from input more characters.

The same with android:lines that only makes the TextView be exactly this many lines tall.



回答6:

The workaround code for your solution are as below,

XML File

    <EditText
            android:id="@+id/full_name_et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5sp"
            android:background="#00ffffff"
            android:imeOptions="actionNext"
            android:inputType="text"
            android:maxLines="1"
            android:maxLength="20"
            android:textCursorDrawable="@null" />

Java:

final EditText edtfirstName = (EditText) findViewById(R.id.full_name_et);


    edtfirstName.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
            if (charSequence.toString().startsWith(" ")) {
                String result = charSequence.toString().replace(" ", "").replaceAll("[^a-zA-Z]+", "");
                if (!charSequence.toString().equals(result)) {
                    edtfirstName.setText(result);
                    edtfirstName.setSelection(result.length());
                }
            } else {
                String result = charSequence.toString().replaceAll("[^a-zA-Z ]+", "");
                if (!charSequence.toString().equals(result)) {
                    edtfirstName.setText(result);
                    edtfirstName.setSelection(result.length());
                }
            }

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });