EditText maxLines가 작동하지 않음-사용자는 여전히 설정된 것보다 더 많은 줄을 입력 할 수 있습니다.


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

사용자는 엔터 / 다음 행 키를 눌러 5 개 이상의 라인을 입력 할 수 있습니다. EditText를 사용하여 사용자 입력을 고정 된 행 수로 제한하려면 어떻게해야합니까?


답변:


85

속성 maxLines은의 최대 높이에 해당 EditText하며 내부 텍스트 행이 아닌 외부 경계를 제어합니다.


그게 내가 생각한 것입니다 ... 입력 된 줄을 제한하는 방법이 있습니까 아니면 프로그래밍 방식으로 백엔드 코드에서해야합니까?
Indrek Kõue 2011-08-17

원하는대로 입력 된 줄을 제한하는 간단한 방법은 없습니다. 코드에서 수동으로 수행해야합니다.
Cedekasme 2011-08-17

3
개발자에게 "maxLines"는 editText로 가능한 최대 줄 수를 의미한다고 생각합니다. 특정 높이를 원하면 "선"을 사용합니다. : - /
어딘가의 누군가가

242
<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
@Neol Chew 당신이 맞아요! 내가 설정 한 후 일 inputTypetext. :-) 내 시간을 절약 주셔서 감사합니다
byJeevan

6
@byJeevan, 나는 항상 inputType에 "text"의 기본값이 있다고 생각했습니다. 내가 틀렸나 봐.
Noel Chew

2
Text가 inputType에 대해 설정된 기본값이 아니라는 점이 매우 이상합니다. 그래도 Great Answer
Muhammed Refaat

9
그것은 단지 하나의 maxLines 작동하지만 당신은 새로운 라인을 추가 할 수 없습니다
다니엘 라우 프에게

69

이것은 n 줄로 제한하는 일반적인 문제를 해결하지 못합니다. EditText가 한 줄의 텍스트 만 사용하도록 제한하려면 매우 간단 할 수 있습니다.
xml 파일에서 설정할 수 있습니다.

android:singleLine="true"

또는 프로그래밍 방식으로

editText.setSingleLine(true);

8
하지만 2 행으로 제한하려면 어떻게해야합니까? 아니면 3? 당신이 빌드 정의 행 제한을 가지고 ... 들어
Indrek Kõue

4
나는 그것을 알고 있습니다. "이것은 n 줄로 제한하는 일반적인 문제를 해결하지 못합니다". 나는 한 줄로 제한하려고 노력하고 더 쉬운 해결책을 찾는 동안 여기에서 질문을 읽었습니다. 나는 다른 사람들이 EditText를 1 줄로 제한하고 "custom row limiter"를 구현하기 위해 여기에있을 것이라고 생각했습니다. 내 대답은 내가 한 것과 같은 이유로이 질문을 검색하는 다른 SO 사용자를 위해 여기에 있습니다.
Jesse Black

@ IndrekKõue 너무 어렵지 않아야합니다.
Don

10
singleLine은 더 이상 사용되지 않습니다
Ali

1
EDITTEXT의 속성을 "true"만일 Singleline =은 더 이상 사용되지 않으며 장치에 충돌 것 안드로이드에서 사용하는보다 큰 7.0
TranHieu

24

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

이것은 사용자에게 직관적이지 않은 부작용이 있습니다. 예를 들어 EditText에 7 줄이 있고 그 중간에 Enter 키를 누르면 텍스트의 마지막 줄에 작별 인사를 할 수 있습니다.
miguel.martin

maxlines 이상의 텍스트를 붙여 넣으면 작동하지 않습니다. 따라서 addTextChangedListener를 사용하는 것이 좋습니다.
Kuldeep Sakhiya

13

나는 너희들이 찾던 것과 같은 것을했다. 여기 내 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);
}

}

2
이 솔루션은 매우 간단하고 우아합니다! 감사합니다
GuilhE 2014 년

콜백 beforeCursorPosition = getSelectionStart();에서 사용 afterTextChanged합니다. 그것은 입력 때 때문에 잘 작동 e입력 후에 abcd는 글고 치기는 '생각'할 수있다 당신이 교체 abcdabcde인해 입력 방법의 이유.
hanswim

11

나는 이것에 대한 더 간단한 해결책을 만들었습니다 : 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);
        }
    });

txtSpecialRequests.getLineCount() > 3필요에 따라 3의 값을 변경할 수 있습니다 .


3
대단히 감사합니다. 마침내 여러 가지 잘못된 해결책을 찾았습니다. 이것은 받아 들여진 대답이어야합니다.
eyadMhanna

"txtSpecialRequests"가 EditText 컨테이너라는 것을 알지만 lastSpecialRequestsCursorPosition 및 specialRequests 변수를 어디에 설정합니까?
drearypanoramic

물론이 방법 밖에 : 초기화 lastSpecialRequestsCursorPosition = 0 specialRequests = ""
오스카 Yuandinata

훌륭한 솔루션!
Marcus

5

다음은 EditText에서 허용되는 줄을 제한하는 InputFilter입니다.

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

좋은 해결책이지만 텍스트 줄 바꿈 (입력하지 않음) 문제를 해결합니다
Peter File

4

이것은 내 프로젝트에서 사용한 것입니다.

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

그리고 그것은 모든 시나리오에서 작동했습니다.


1
TextWatcher에는 어떤 컨텍스트가 필요합니까? KeyListener 만 있으면됩니다.
AlanKley 2013-04-30

@AlanKley : editText의 줄 수를 계산하려면 텍스트 변경 전후 이벤트가 필요합니다. 텍스트를 계속 입력하고 "new line"키를 누르지 않는 것처럼 onKey가 실행되지 않고 커서가 자동으로 다음 줄로 이동합니다. 따라서 이러한 종류의 줄을 추적하려면 textWatcher가 필요합니다. 내가 당신을 이해할 수 있기를 바랍니다.
Pirate

내가 참조. 설명해 주셔서 감사합니다.
AlanKley 2013-04-30

@AlanKley 내 대답이 유용하다고 생각되면 투표하십시오.
Pirate

public void afterTextChanged (Editable arg0) {int lineCount = editText.getLineCount (); if (lineCount> numberOfLines) {editText.setText (text); }} StackOverflowException이 발생합니다 ...
desgraci


3

가장 간단한 솔루션 :

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


2

이것은 하나의 접근 방식입니다. 누군가를 도울 수 있습니다.

android:lines="1"
android:maxLines="1"
android:inputType="text

1

EditText한 줄로 제한하는 또 다른 방법 은 다음과 같습니다.

editText2.setTransformationMethod(new SingleLineTransformationMethod());

이 변환 방법을 적용한 후 Enter 키를 누르면 공백이 생성됩니다. 그것은 여전히 ​​TS의 질문을 만족시킵니다.


새로운 라인을 숨기는 좋은 방법! 그러나 값에는 여전히 '새 줄'문자가 있습니다 !!
Gregory Stein

1

내가 말하는 줄 수에 따라 텍스트를 제한 할 수 있습니다. 한 줄에 약 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"/>

0

getLineCount ()는 하나의 옵션입니다. 0이 아닌 값을 원하면 뷰가 측정되었는지 확인하십시오. 소프트 키보드의 경우 onKeyListener가 작동하지 않으므로 입력 할 때 텍스트 변경을 추적하는 addTextChangedListener ()를 추가해야합니다. 콜백 내부에 충분한 줄이 생기면 제한하려는 모든 작업을 수행합니다. getText (), setText () 또는 더 멋진 것을 사용하여 문자를 삭제합니다. 필터를 사용하여 문자 수를 제한 할 수도 있습니다.

또 다른 옵션은 getLineBounds ()로 텍스트의 크기를 모니터링하는 것입니다. 이것은 텍스트 중력 / 패드와 상호 작용하므로주의하십시오.


0

문자 수를 제한하려면 사용자가 더 많은 문자를 입력 할 수 없기 때문에 EditText의 maxLength 속성을 사용하면됩니다.


0
        <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

또 다른 아이디어 : 입력 후 매번 새 텍스트는 줄 수가 MAX_LINES를 초과하지 않는 경우에만 String lastText에 저장됩니다. 그렇다면 EditText의 텍스트를 마지막으로 추가 된 텍스트로 설정하고 (변경 사항이 삭제됨) 사용자에게 짧게 유지하도록 알립니다.

 // Set listener to wishDescriptionEditText in order to limit line number
    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 line account is higher than MAX_LINES, set text to lastText
            // and notify user (by Toast)
            if (editText.getLineCount() > MAX_LINES) {
                editText.setText(lastText);
                Toast.makeText(getContext(), "Please keep it short", Toast.LENGTH_LONG).show();
            } else {
                lastText = editText.getText().toString();
            }
        }
    });

0

이것은 Kotlin에 대한 Indrek Kõue 답변 의 확장입니다.

                input_name.addTextChangedListener(object : TextWatcher {
                override fun afterTextChanged(s: Editable?) {}

                override fun beforeTextChanged(
                    s: CharSequence?,
                    start: Int,
                    count: Int,
                    after: Int
                ) {
                }

                @SuppressLint("SetTextI18n")
                override fun onTextChanged(
                    s: CharSequence?,
                    start: Int,
                    before: Int,
                    count: Int
                ) {
                    val text = (input_name as EditText).text.toString()
                    val editTextRowCount = input_name.lineCount
                    if (editTextRowCount > 15) {
                        val newText = text.substring(0, text.length - 1)
                        input_name.setText("")
                        input_name.append(newText)
                    }
                }
            })

-4

xml 파일 내에서 다음과 같은 EditText 속성 조합을 사용해보십시오.

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


2
그냥주의하세요. singleLine은 더 이상 사용되지 않습니다. maxLines는 singleLine 대신 도입되었습니다.
Sandeep R

@SandeepR 당신은 틀렸다, android:inputType사용을 대체합니다android:singleLine
Pierre
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.