EditText maxLines не работает - пользователь может все еще вводить больше строк, чем установлено

<EditText 
    android:id="@+id/editText2" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:maxLines="5" 
    android:lines="5">
</EditText>

Пользователь может ввести более 5 строк, нажав клавишу ввода/следующей строки. Как я могу ограничить ввод пользователя фиксированным количеством строк с помощью EditText?

Ответ 1

Атрибут maxLines соответствует максимальной высоте EditText, он управляет внешними границами, а не внутренними текстовыми строками.

Ответ 2

<EditText
    android:id="@+id/edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:maxLines="1" 
/>

Вам просто нужно убедиться, что у вас установлен атрибут "inputType". Это не работает без этой строки.

android:inputType="text"

Ответ 3

Это не решает общей проблемы ограничения n строк. Если вы хотите ограничить редактирование текста EditText только одной строкой текста, это может быть очень просто.
Вы можете установить это в файле xml.

android:singleLine="true"

или программно

editText.setSingleLine(true);

Ответ 4

@Cedekasem вы правы, нет встроенного ограничителя строк. Но я сам построил свое, поэтому, если кому-то интересно, код ниже. Приветствия.

et.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            // if enter is pressed start calculating
            if (keyCode == KeyEvent.KEYCODE_ENTER
                    && event.getAction() == KeyEvent.ACTION_UP) {

                // get EditText text
                String text = ((EditText) v).getText().toString();

                // find how many rows it cointains
                int editTextRowCount = text.split("\\n").length;

                // user has input more than limited - lets do something
                // about that
                if (editTextRowCount >= 7) {

                    // find the last break
                    int lastBreakIndex = text.lastIndexOf("\n");

                    // compose new text
                    String newText = text.substring(0, lastBreakIndex);

                    // add new text - delete old one and append new one
                    // (append because I want the cursor to be at the end)
                    ((EditText) v).setText("");
                    ((EditText) v).append(newText);

                }
            }

            return false;
        }
});

Ответ 5

Я сделал то, что вы, ребята, искали. Здесь мой класс LimitedEditText.

Особенности:

  • вы можете ограничить количество строк в компоненте LimitedEditText
  • вы можете ограничить количество символов в компоненте LimitedEditText
  • Если вы превысите лимит символов или строк где-то в середине текста, курсор не приведет вас к концу - он останется там, где вы были.

Im отключает прослушиватель, потому что каждый вызов метода setText() рекурсивно вызывает эти три метода обратного вызова в случае, если пользователь превысил лимит символов или строк.

код:

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;

/**
* EditText subclass created to enforce limit of the lines number in editable
* text field
*/
public class LimitedEditText extends EditText {

/**
 * Max lines to be present in editable text field
 */
private int maxLines = 1;

/**
 * Max characters to be present in editable text field
 */
private int maxCharacters = 50;

/**
 * application context;
 */
private Context context;

public int getMaxCharacters() {
    return maxCharacters;
}

public void setMaxCharacters(int maxCharacters) {
    this.maxCharacters = maxCharacters;
}

@Override
public int getMaxLines() {
    return maxLines;
}

@Override
public void setMaxLines(int maxLines) {
    this.maxLines = maxLines;
}

public LimitedEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
}

public LimitedEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
}

public LimitedEditText(Context context) {
    super(context);
    this.context = context;
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    TextWatcher watcher = new TextWatcher() {

        private String text;
        private int beforeCursorPosition = 0;

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

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            text = s.toString();
            beforeCursorPosition = start;
        }

        @Override
        public void afterTextChanged(Editable s) {

            /* turning off listener */
            removeTextChangedListener(this);

            /* handling lines limit exceed */
            if (LimitedEditText.this.getLineCount() > maxLines) {
                LimitedEditText.this.setText(text);
                LimitedEditText.this.setSelection(beforeCursorPosition);
            }

            /* handling character limit exceed */
            if (s.toString().length() > maxCharacters) {
                LimitedEditText.this.setText(text);
                LimitedEditText.this.setSelection(beforeCursorPosition);
                Toast.makeText(context, "text too long", Toast.LENGTH_SHORT)
                        .show();
            }

            /* turning on listener */
            addTextChangedListener(this);

        }
    };

    this.addTextChangedListener(watcher);
}

}

Ответ 6

Я сделал более простое решение для этого: D

// set listeners
    txtSpecialRequests.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            lastSpecialRequestsCursorPosition = txtSpecialRequests.getSelectionStart();
        }

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

        }

        @Override
        public void afterTextChanged(Editable s) {
            txtSpecialRequests.removeTextChangedListener(this);

            if (txtSpecialRequests.getLineCount() > 3) {
                txtSpecialRequests.setText(specialRequests);
                txtSpecialRequests.setSelection(lastSpecialRequestsCursorPosition);
            }
            else
                specialRequests = txtSpecialRequests.getText().toString();

            txtSpecialRequests.addTextChangedListener(this);
        }
    });

Вы можете изменить значение 3 в txtSpecialRequests.getLineCount() > 3 в соответствии с вашими потребностями.

Ответ 7

Вот InputFilter, который ограничивает допустимые строки в EditText:

/**
 * Filter for controlling maximum new lines in EditText.
 */
public class MaxLinesInputFilter implements InputFilter {

  private final int mMax;

  public MaxLinesInputFilter(int max) {
    mMax = max;
  }

  public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    int newLinesToBeAdded = countOccurrences(source.toString(), '\n');
    int newLinesBefore = countOccurrences(dest.toString(), '\n');
    if (newLinesBefore >= mMax - 1 && newLinesToBeAdded > 0) {
      // filter
      return "";
    }

    // do nothing
    return null;
  }

  /**
   * @return the maximum lines enforced by this input filter
   */
  public int getMax() {
    return mMax;
  }

  /**
   * Counts the number occurrences of the given char.
   *
   * @param string the string
   * @param charAppearance the char
   * @return number of occurrences of the char
   */
  public static int countOccurrences(String string, char charAppearance) {
    int count = 0;
    for (int i = 0; i < string.length(); i++) {
      if (string.charAt(i) == charAppearance) {
        count++;
      }
    }
    return count;
  }
}

Чтобы добавить его в EditText:

editText.setFilters(new InputFilter[]{new MaxLinesInputFilter(2)});

Ответ 8

Это то, что я использовал в своем проекте:

editText.addTextChangedListener(new TextWatcher() {
    private String text;

public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {    
}

public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
    text = arg0.toString();
    }

public void afterTextChanged(Editable arg0) {
    int lineCount = editText.getLineCount();
    if(lineCount > numberOfLines){
    editText.setText(text);
    }
}
});

editText.setOnKeyListener(new View.OnKeyListener() {

public boolean onKey(View v, int keyCode, KeyEvent event) {

// if enter is pressed start calculating
    if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN){    
    int editTextLineCount = ((EditText)v).getLineCount();
    if (editTextLineCount >= numberOfLines)
        return true;
}

return false;
}
});

И он работал во всех сценариях

Ответ 9

getLineCount() - один из вариантов; если вы хотите отличные от нуля значения, убедитесь, что ваш вид измерен. Для мягкой клавиатуры onKeyListener не будет работать, поэтому вам нужно добавить addTextChangedListener(), который будет отслеживать изменения текста по мере ввода. Как только вы получите достаточное количество строк внутри своих обратных вызовов, сделайте все, что вы хотите ограничить: удалите символы с getText(), setText() или что-то более фантастическое. Вы можете даже ограничить количество символов с помощью фильтра.

Другой вариант - контролировать размер текста с помощью getLineBounds(). Это будет взаимодействовать с гравитацией текста /paddign, поэтому будьте осторожны.

Ответ 10

Для предельного числа символов мы можем просто использовать свойство maxLength для EditText, так как оно не позволит пользователю вводить больше символов.

Ответ 11

Самое простое решение:

android:maxLines="3"

...

 @Override
public void afterTextChanged(Editable editable) {
    // limit to 3 lines
    if (editText.getLayout().getLineCount() > 3)
        editText.getText().delete(editText.getText().length() - 1, editText.getText().length());
}

Ответ 12

Другой способ ограничить EditText одной строкой:

editText2.setTransformationMethod(new SingleLineTransformationMethod());

Обратите внимание, что после применения этого метода преобразования клавиша ввода создает пробелы при нажатии. Это все еще удовлетворяет вопросу TS.

Ответ 13

Попробуйте использовать следующую комбинацию атрибутов EditText внутри xml файла:

android:singleLine="true"
android:maxLength="22"