it-roy-ru.com

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?

97
Indrek Kõue

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

68
Cedekasme
<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"
187
Noel Chew

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

Android:singleLine="true"

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

editText.setSingleLine(true);
62
Jesse Black

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

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;
        }
});
23
Indrek Kõue

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

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

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

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

Код:

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);
}

}
12
bpawlowski

Я сделал более простое решение для этого: 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 в соответствии с вашими потребностями.

10
Oscar Yuandinata

Вот 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)});
5
peceps

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

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;
}
});

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

4
Pirate

это один из подходов. Может помочь кому-нибудь.

Android:lines="1"
Android:maxLines="1"
Android:inputType="text
1
mohammed nathar

Другой способ ограничить EditText одной строкой заключается в следующем:

editText2.setTransformationMethod(new SingleLineTransformationMethod());

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

1
giorgos29cm

Вы можете ограничить свой текст в соответствии с вашим количеством строк, я говорю около 37 алфавитов в одной строке

<EditText
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:lines="4"
    Android:maxLines="4"
    Android:minLines="4"
    Android:maxLength="150"
    Android:gravity="start"
    Android:background="#efeef5"
    Android:layout_marginTop="@dimen/pad_10dp"/>
1
nafees ahmed

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

0
Pirate

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

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());
}
0
landonmutch

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

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

0
Vlad
        <EditText
            Android:id="@+id/usrusr"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_gravity="center"
            Android:gravity="center"
            Android:lines="1"
            Android:maxLines="1"
            Android:inputType="text"
            Android:hint="@string/inventory_no" />
0
Atiar Talukdar