限制Android中EditText的文本长度

时间:2021-08-08 21:45:34

What's the best way to limit the text length of an EditText in Android?

在Android中,限制EditText文本长度的最好方法是什么?

Is there a way to do this via xml?

有办法通过xml实现这一点吗?

15 个解决方案

#1


1078  

Documentation

文档

Example

例子

android:maxLength="10"

#2


287  

use an input filter to limit the max length of a text view.

使用输入过滤器来限制文本视图的最大长度。

TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);

#3


161  

EditText editText = new EditText(this);
int maxLength = 3;    
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});

#4


59  

A note to people who are already using a custom input filter and also want to limit the max length:

给已经在使用自定义输入过滤器并且想要限制最大长度的人的提示:

When you assign input filters in code all previously set input filters are cleared, including one set with android:maxLength. I found this out when attempting to use a custom input filter to prevent the use of some characters that we don't allow in a password field. After setting that filter with setFilters the maxLength was no longer observed. The solution was to set maxLength and my custom filter together programmatically. Something like this:

当您在代码中分配输入过滤器时,所有先前设置的输入过滤器都将被清除,包括与android:maxLength一起设置的一个。我在尝试使用自定义输入过滤器来防止使用密码字段中不允许的字符时发现了这一点。使用setfilter设置过滤器之后,maxLength将不再被观察到。解决方案是通过编程方式设置maxLength和我的自定义过滤器。是这样的:

myEditText.setFilters(new InputFilter[] {
        new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});

#5


32  

TextView tv = new TextView(this);
tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) });

#6


21  

For anyone else wondering how to achieve this, here is my extended EditText class EditTextNumeric.

对于任何想要实现这一点的人,这里是我的扩展EditText类EditTextNumeric。

.setMaxLength(int) - sets maximum number of digits

.setMaxLength(int) -设置最大位数

.setMaxValue(int) - limit maximum integer value

.setMaxValue(int)——限制最大整数值

.setMin(int) - limit minimum integer value

.setMin(int)——限制最小整数值

.getValue() - get integer value

.getValue() -获取整数值

import android.content.Context;
import android.text.InputFilter;
import android.text.InputType;
import android.widget.EditText;

public class EditTextNumeric extends EditText {
    protected int max_value = Integer.MAX_VALUE;
    protected int min_value = Integer.MIN_VALUE;

    // constructor
    public EditTextNumeric(Context context) {
        super(context);
        this.setInputType(InputType.TYPE_CLASS_NUMBER);
    }

    // checks whether the limits are set and corrects them if not within limits
    @Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        if (max_value != Integer.MAX_VALUE) {
            try {
                if (Integer.parseInt(this.getText().toString()) > max_value) {
                    // change value and keep cursor position
                    int selection = this.getSelectionStart();
                    this.setText(String.valueOf(max_value));
                    if (selection >= this.getText().toString().length()) {
                        selection = this.getText().toString().length();
                    }
                    this.setSelection(selection);
                }
            } catch (NumberFormatException exception) {
                super.onTextChanged(text, start, before, after);
            }
        }
        if (min_value != Integer.MIN_VALUE) {
            try {
                if (Integer.parseInt(this.getText().toString()) < min_value) {
                    // change value and keep cursor position
                    int selection = this.getSelectionStart();
                    this.setText(String.valueOf(min_value));
                    if (selection >= this.getText().toString().length()) {
                        selection = this.getText().toString().length();
                    }
                    this.setSelection(selection);
                }
            } catch (NumberFormatException exception) {
                super.onTextChanged(text, start, before, after);
            }
        }
        super.onTextChanged(text, start, before, after);
    }

    // set the max number of digits the user can enter
    public void setMaxLength(int length) {
        InputFilter[] FilterArray = new InputFilter[1];
        FilterArray[0] = new InputFilter.LengthFilter(length);
        this.setFilters(FilterArray);
    }

    // set the maximum integer value the user can enter.
    // if exeeded, input value will become equal to the set limit
    public void setMaxValue(int value) {
        max_value = value;
    }
    // set the minimum integer value the user can enter.
    // if entered value is inferior, input value will become equal to the set limit
    public void setMinValue(int value) {
        min_value = value;
    }

    // returns integer value or 0 if errorous value
    public int getValue() {
        try {
            return Integer.parseInt(this.getText().toString());
        } catch (NumberFormatException exception) {
            return 0;
        }
    }
}

Example usage:

使用示例:

final EditTextNumeric input = new EditTextNumeric(this);
input.setMaxLength(5);
input.setMaxValue(total_pages);
input.setMinValue(1);

All other methods and attributes that apply to EditText, of course work too.

当然,应用于EditText的所有其他方法和属性也可以工作。

#7


17  

Due to goto10's observation, I put together the following code to protected against loosing other filters with setting the max length:

由于goto10的观察,我将下面的代码组合在一起,以防止在设置最大长度时丢失其他过滤器:

/**
 * This sets the maximum length in characters of an EditText view. Since the
 * max length must be done with a filter, this method gets the current
 * filters. If there is already a length filter in the view, it will replace
 * it, otherwise, it will add the max length filter preserving the other
 * 
 * @param view
 * @param length
 */
public static void setMaxLength(EditText view, int length) {
    InputFilter curFilters[];
    InputFilter.LengthFilter lengthFilter;
    int idx;

    lengthFilter = new InputFilter.LengthFilter(length);

    curFilters = view.getFilters();
    if (curFilters != null) {
        for (idx = 0; idx < curFilters.length; idx++) {
            if (curFilters[idx] instanceof InputFilter.LengthFilter) {
                curFilters[idx] = lengthFilter;
                return;
            }
        }

        // since the length filter was not part of the list, but
        // there are filters, then add the length filter
        InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
        System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
        newFilters[curFilters.length] = lengthFilter;
        view.setFilters(newFilters);
    } else {
        view.setFilters(new InputFilter[] { lengthFilter });
    }
}

#8


8  

Another way you can achieve this is by adding the following definition to the XML file:

另一种实现方法是将以下定义添加到XML文件:

<EditText
    android:id="@+id/input"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:inputType="number"
    android:maxLength="6"
    android:hint="@string/hint_gov"
    android:layout_weight="1"/>

This will limit the maximum length of the EditText widget to 6 characters.

这将限制EditText小部件的最大长度为6个字符。

#9


7  

//Set Length filter. Restricting to 10 characters only
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH)});

//Allowing only upper case characters
editText.setFilters(new InputFilter[]{new InputFilter.AllCaps()});

//Attaching multiple filters
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH), new InputFilter.AllCaps()});

#10


6  

I have had this problem and I consider we are missing a well explained way of doing this programmatically without losing the already set filters.

我已经遇到了这个问题,我认为我们缺少一个很好的解释方法,可以在不丢失已设置的过滤器的情况下进行编程。

Setting the length in XML:

在XML中设置长度:

As the accepted answer states correctly, if you want to define a fixed length to an EditText which you won't change further in the future just define in your EditText XML:

正如所接受的答案所指出的那样,如果您希望为EditText定义一个固定长度,并且以后不会再更改它,那么只需在EditText XML中定义:

android:maxLength="10" 

Setting the length programmatically

以编程方式设置长度

Heres the problem, to set the length programmatically you will need to set an InputFilter but once you set it all the other filters go away (e.g. maxLines, inputType, etc). To avoid losing previous filters you need to get those previous applied filters, add the maxLength, and set the filters back to the EditText as follow:

这里的问题是,要以编程的方式设置长度,您需要设置一个InputFilter,但是一旦设置了它,其他的过滤器就会消失(比如maxLines、inputType等)。为了避免丢失先前的过滤器,您需要获得先前应用的过滤器,添加maxLength,并将过滤器设置回EditText,如下所示:

InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(10); //the desired length
editText.setFilters(newFilters);

#11


2  

This is a custom EditText Class that allow Length filter to live along with other filters. Thanks to Tim Gallagher's Answer (below)

这是一个自定义EditText类,允许长度过滤器与其他过滤器一起工作。感谢蒂姆·加拉格尔(Tim Gallagher)的回答(见下文)

import android.content.Context;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.widget.EditText;


public class EditTextMultiFiltering extends EditText{

    public EditTextMultiFiltering(Context context) {
        super(context);
    }

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

    public EditTextMultiFiltering(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setMaxLength(int length) {
        InputFilter curFilters[];
        InputFilter.LengthFilter lengthFilter;
        int idx;

        lengthFilter = new InputFilter.LengthFilter(length);

        curFilters = this.getFilters();
        if (curFilters != null) {
            for (idx = 0; idx < curFilters.length; idx++) {
                if (curFilters[idx] instanceof InputFilter.LengthFilter) {
                    curFilters[idx] = lengthFilter;
                    return;
                }
            }

            // since the length filter was not part of the list, but
            // there are filters, then add the length filter
            InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
            System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
            newFilters[curFilters.length] = lengthFilter;
            this.setFilters(newFilters);
        } else {
            this.setFilters(new InputFilter[] { lengthFilter });
        }
    }
}

#12


2  

This works fine...

这没问题…

android:maxLength="10"

android:最大长度= " 10 "

this will accept only 10 characters.

这将只接受10个字符。

#13


1  

it simple way in xml:

xml的简单方式:

android:maxLength="4"

if u require to set 4 character in xml edit-text so,use this

如果您需要在xml编辑-文本中设置4个字符,请使用这个

<EditText
    android:id="@+id/edtUserCode"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:maxLength="4"
    android:hint="Enter user code" />

#14


1  

I had saw a lot of good solutions, but I'd like to give a what I think as more complete and user-friendly solution, which include:

我已经看到了很多好的解决方案,但是我想给出一个我认为更完整和用户友好的解决方案,包括:

1, Limit length.
2, If input more, give a callback to trigger your toast.
3, Cursor can be at middle or tail.
4, User can input by paste a string.
5, Always discard overflow input and keep origin.

1、限制长度。如果输入更多,请回调以触发你的吐司。光标可以在中间或尾部。用户可以通过粘贴一个字符串进行输入。5、总是丢弃溢出输入,保持原点。

public class LimitTextWatcher implements TextWatcher {

    public interface IF_callback{
        void callback(int left);
    }

    public IF_callback if_callback;

    EditText editText;
    int maxLength;

    int cursorPositionLast;
    String textLast;
    boolean bypass;

    public LimitTextWatcher(EditText editText, int maxLength, IF_callback if_callback) {

        this.editText = editText;
        this.maxLength = maxLength;
        this.if_callback = if_callback;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        if (bypass) {

            bypass = false;

        } else {

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(s);
            textLast = stringBuilder.toString();

            this.cursorPositionLast = editText.getSelectionStart();
        }
    }

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

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (s.toString().length() > maxLength) {

            int left = maxLength - s.toString().length();

            bypass = true;
            s.clear();

            bypass = true;
            s.append(textLast);

            editText.setSelection(this.cursorPositionLast);

            if (if_callback != null) {
                if_callback.callback(left);
            }
        }

    }

}


edit_text.addTextChangedListener(new LimitTextWatcher(edit_text, MAX_LENGTH, new LimitTextWatcher.IF_callback() {
    @Override
    public void callback(int left) {
        if(left <= 0) {
            Toast.makeText(MainActivity.this, "input is full", Toast.LENGTH_SHORT).show();
        }
    }
}));

What I failed to do is, if user highlight a part of the current input and try to paste an very long string, I don't know how to restore the highlight.

我没有做的是,如果用户高亮显示当前输入的一部分,并尝试粘贴一个非常长的字符串,我不知道如何恢复高亮显示。

Such as, max length is set to 10, user inputed '12345678', and mark '345' as highlight, and try to paste a string of '0000' which will exceed limitation.

例如,最大长度设置为10,用户输入“12345678”,标记“345”作为突出显示,并尝试粘贴一个超过限制的“0000”字符串。

When I try to use edit_text.setSelection(start=2, end=4) to restore origin status, the result is, it just insert 2 space as '12 345 678', not the origin highlight. I'd like someone solve that.

当我尝试使用edit_text时。setSelection(start=2, end=4)恢复原点状态,结果是,它只插入2个空格作为“12345 678”,而不是原点高亮显示。我希望有人能解决这个问题。

#15


1  

You can use android:maxLength="10" in the edittext.(Here the limit is upto 10 characters)

您可以在edittext中使用android:maxLength="10"。(这里的限制是最多10个字符)

#1


1078  

Documentation

文档

Example

例子

android:maxLength="10"

#2


287  

use an input filter to limit the max length of a text view.

使用输入过滤器来限制文本视图的最大长度。

TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);

#3


161  

EditText editText = new EditText(this);
int maxLength = 3;    
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});

#4


59  

A note to people who are already using a custom input filter and also want to limit the max length:

给已经在使用自定义输入过滤器并且想要限制最大长度的人的提示:

When you assign input filters in code all previously set input filters are cleared, including one set with android:maxLength. I found this out when attempting to use a custom input filter to prevent the use of some characters that we don't allow in a password field. After setting that filter with setFilters the maxLength was no longer observed. The solution was to set maxLength and my custom filter together programmatically. Something like this:

当您在代码中分配输入过滤器时,所有先前设置的输入过滤器都将被清除,包括与android:maxLength一起设置的一个。我在尝试使用自定义输入过滤器来防止使用密码字段中不允许的字符时发现了这一点。使用setfilter设置过滤器之后,maxLength将不再被观察到。解决方案是通过编程方式设置maxLength和我的自定义过滤器。是这样的:

myEditText.setFilters(new InputFilter[] {
        new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});

#5


32  

TextView tv = new TextView(this);
tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) });

#6


21  

For anyone else wondering how to achieve this, here is my extended EditText class EditTextNumeric.

对于任何想要实现这一点的人,这里是我的扩展EditText类EditTextNumeric。

.setMaxLength(int) - sets maximum number of digits

.setMaxLength(int) -设置最大位数

.setMaxValue(int) - limit maximum integer value

.setMaxValue(int)——限制最大整数值

.setMin(int) - limit minimum integer value

.setMin(int)——限制最小整数值

.getValue() - get integer value

.getValue() -获取整数值

import android.content.Context;
import android.text.InputFilter;
import android.text.InputType;
import android.widget.EditText;

public class EditTextNumeric extends EditText {
    protected int max_value = Integer.MAX_VALUE;
    protected int min_value = Integer.MIN_VALUE;

    // constructor
    public EditTextNumeric(Context context) {
        super(context);
        this.setInputType(InputType.TYPE_CLASS_NUMBER);
    }

    // checks whether the limits are set and corrects them if not within limits
    @Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        if (max_value != Integer.MAX_VALUE) {
            try {
                if (Integer.parseInt(this.getText().toString()) > max_value) {
                    // change value and keep cursor position
                    int selection = this.getSelectionStart();
                    this.setText(String.valueOf(max_value));
                    if (selection >= this.getText().toString().length()) {
                        selection = this.getText().toString().length();
                    }
                    this.setSelection(selection);
                }
            } catch (NumberFormatException exception) {
                super.onTextChanged(text, start, before, after);
            }
        }
        if (min_value != Integer.MIN_VALUE) {
            try {
                if (Integer.parseInt(this.getText().toString()) < min_value) {
                    // change value and keep cursor position
                    int selection = this.getSelectionStart();
                    this.setText(String.valueOf(min_value));
                    if (selection >= this.getText().toString().length()) {
                        selection = this.getText().toString().length();
                    }
                    this.setSelection(selection);
                }
            } catch (NumberFormatException exception) {
                super.onTextChanged(text, start, before, after);
            }
        }
        super.onTextChanged(text, start, before, after);
    }

    // set the max number of digits the user can enter
    public void setMaxLength(int length) {
        InputFilter[] FilterArray = new InputFilter[1];
        FilterArray[0] = new InputFilter.LengthFilter(length);
        this.setFilters(FilterArray);
    }

    // set the maximum integer value the user can enter.
    // if exeeded, input value will become equal to the set limit
    public void setMaxValue(int value) {
        max_value = value;
    }
    // set the minimum integer value the user can enter.
    // if entered value is inferior, input value will become equal to the set limit
    public void setMinValue(int value) {
        min_value = value;
    }

    // returns integer value or 0 if errorous value
    public int getValue() {
        try {
            return Integer.parseInt(this.getText().toString());
        } catch (NumberFormatException exception) {
            return 0;
        }
    }
}

Example usage:

使用示例:

final EditTextNumeric input = new EditTextNumeric(this);
input.setMaxLength(5);
input.setMaxValue(total_pages);
input.setMinValue(1);

All other methods and attributes that apply to EditText, of course work too.

当然,应用于EditText的所有其他方法和属性也可以工作。

#7


17  

Due to goto10's observation, I put together the following code to protected against loosing other filters with setting the max length:

由于goto10的观察,我将下面的代码组合在一起,以防止在设置最大长度时丢失其他过滤器:

/**
 * This sets the maximum length in characters of an EditText view. Since the
 * max length must be done with a filter, this method gets the current
 * filters. If there is already a length filter in the view, it will replace
 * it, otherwise, it will add the max length filter preserving the other
 * 
 * @param view
 * @param length
 */
public static void setMaxLength(EditText view, int length) {
    InputFilter curFilters[];
    InputFilter.LengthFilter lengthFilter;
    int idx;

    lengthFilter = new InputFilter.LengthFilter(length);

    curFilters = view.getFilters();
    if (curFilters != null) {
        for (idx = 0; idx < curFilters.length; idx++) {
            if (curFilters[idx] instanceof InputFilter.LengthFilter) {
                curFilters[idx] = lengthFilter;
                return;
            }
        }

        // since the length filter was not part of the list, but
        // there are filters, then add the length filter
        InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
        System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
        newFilters[curFilters.length] = lengthFilter;
        view.setFilters(newFilters);
    } else {
        view.setFilters(new InputFilter[] { lengthFilter });
    }
}

#8


8  

Another way you can achieve this is by adding the following definition to the XML file:

另一种实现方法是将以下定义添加到XML文件:

<EditText
    android:id="@+id/input"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:inputType="number"
    android:maxLength="6"
    android:hint="@string/hint_gov"
    android:layout_weight="1"/>

This will limit the maximum length of the EditText widget to 6 characters.

这将限制EditText小部件的最大长度为6个字符。

#9


7  

//Set Length filter. Restricting to 10 characters only
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH)});

//Allowing only upper case characters
editText.setFilters(new InputFilter[]{new InputFilter.AllCaps()});

//Attaching multiple filters
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH), new InputFilter.AllCaps()});

#10


6  

I have had this problem and I consider we are missing a well explained way of doing this programmatically without losing the already set filters.

我已经遇到了这个问题,我认为我们缺少一个很好的解释方法,可以在不丢失已设置的过滤器的情况下进行编程。

Setting the length in XML:

在XML中设置长度:

As the accepted answer states correctly, if you want to define a fixed length to an EditText which you won't change further in the future just define in your EditText XML:

正如所接受的答案所指出的那样,如果您希望为EditText定义一个固定长度,并且以后不会再更改它,那么只需在EditText XML中定义:

android:maxLength="10" 

Setting the length programmatically

以编程方式设置长度

Heres the problem, to set the length programmatically you will need to set an InputFilter but once you set it all the other filters go away (e.g. maxLines, inputType, etc). To avoid losing previous filters you need to get those previous applied filters, add the maxLength, and set the filters back to the EditText as follow:

这里的问题是,要以编程的方式设置长度,您需要设置一个InputFilter,但是一旦设置了它,其他的过滤器就会消失(比如maxLines、inputType等)。为了避免丢失先前的过滤器,您需要获得先前应用的过滤器,添加maxLength,并将过滤器设置回EditText,如下所示:

InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(10); //the desired length
editText.setFilters(newFilters);

#11


2  

This is a custom EditText Class that allow Length filter to live along with other filters. Thanks to Tim Gallagher's Answer (below)

这是一个自定义EditText类,允许长度过滤器与其他过滤器一起工作。感谢蒂姆·加拉格尔(Tim Gallagher)的回答(见下文)

import android.content.Context;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.widget.EditText;


public class EditTextMultiFiltering extends EditText{

    public EditTextMultiFiltering(Context context) {
        super(context);
    }

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

    public EditTextMultiFiltering(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setMaxLength(int length) {
        InputFilter curFilters[];
        InputFilter.LengthFilter lengthFilter;
        int idx;

        lengthFilter = new InputFilter.LengthFilter(length);

        curFilters = this.getFilters();
        if (curFilters != null) {
            for (idx = 0; idx < curFilters.length; idx++) {
                if (curFilters[idx] instanceof InputFilter.LengthFilter) {
                    curFilters[idx] = lengthFilter;
                    return;
                }
            }

            // since the length filter was not part of the list, but
            // there are filters, then add the length filter
            InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
            System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
            newFilters[curFilters.length] = lengthFilter;
            this.setFilters(newFilters);
        } else {
            this.setFilters(new InputFilter[] { lengthFilter });
        }
    }
}

#12


2  

This works fine...

这没问题…

android:maxLength="10"

android:最大长度= " 10 "

this will accept only 10 characters.

这将只接受10个字符。

#13


1  

it simple way in xml:

xml的简单方式:

android:maxLength="4"

if u require to set 4 character in xml edit-text so,use this

如果您需要在xml编辑-文本中设置4个字符,请使用这个

<EditText
    android:id="@+id/edtUserCode"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:maxLength="4"
    android:hint="Enter user code" />

#14


1  

I had saw a lot of good solutions, but I'd like to give a what I think as more complete and user-friendly solution, which include:

我已经看到了很多好的解决方案,但是我想给出一个我认为更完整和用户友好的解决方案,包括:

1, Limit length.
2, If input more, give a callback to trigger your toast.
3, Cursor can be at middle or tail.
4, User can input by paste a string.
5, Always discard overflow input and keep origin.

1、限制长度。如果输入更多,请回调以触发你的吐司。光标可以在中间或尾部。用户可以通过粘贴一个字符串进行输入。5、总是丢弃溢出输入,保持原点。

public class LimitTextWatcher implements TextWatcher {

    public interface IF_callback{
        void callback(int left);
    }

    public IF_callback if_callback;

    EditText editText;
    int maxLength;

    int cursorPositionLast;
    String textLast;
    boolean bypass;

    public LimitTextWatcher(EditText editText, int maxLength, IF_callback if_callback) {

        this.editText = editText;
        this.maxLength = maxLength;
        this.if_callback = if_callback;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        if (bypass) {

            bypass = false;

        } else {

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(s);
            textLast = stringBuilder.toString();

            this.cursorPositionLast = editText.getSelectionStart();
        }
    }

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

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (s.toString().length() > maxLength) {

            int left = maxLength - s.toString().length();

            bypass = true;
            s.clear();

            bypass = true;
            s.append(textLast);

            editText.setSelection(this.cursorPositionLast);

            if (if_callback != null) {
                if_callback.callback(left);
            }
        }

    }

}


edit_text.addTextChangedListener(new LimitTextWatcher(edit_text, MAX_LENGTH, new LimitTextWatcher.IF_callback() {
    @Override
    public void callback(int left) {
        if(left <= 0) {
            Toast.makeText(MainActivity.this, "input is full", Toast.LENGTH_SHORT).show();
        }
    }
}));

What I failed to do is, if user highlight a part of the current input and try to paste an very long string, I don't know how to restore the highlight.

我没有做的是,如果用户高亮显示当前输入的一部分,并尝试粘贴一个非常长的字符串,我不知道如何恢复高亮显示。

Such as, max length is set to 10, user inputed '12345678', and mark '345' as highlight, and try to paste a string of '0000' which will exceed limitation.

例如,最大长度设置为10,用户输入“12345678”,标记“345”作为突出显示,并尝试粘贴一个超过限制的“0000”字符串。

When I try to use edit_text.setSelection(start=2, end=4) to restore origin status, the result is, it just insert 2 space as '12 345 678', not the origin highlight. I'd like someone solve that.

当我尝试使用edit_text时。setSelection(start=2, end=4)恢复原点状态,结果是,它只插入2个空格作为“12345 678”,而不是原点高亮显示。我希望有人能解决这个问题。

#15


1  

You can use android:maxLength="10" in the edittext.(Here the limit is upto 10 characters)

您可以在edittext中使用android:maxLength="10"。(这里的限制是最多10个字符)