EditText maxLinesが機能しない-ユーザーは設定よりも多くの行を入力できます


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

ユーザーは、Enter /次の行キーを押すことにより、5行以上を入力できます。EditTextを使用して、ユーザー入力を一定の行数に制限するにはどうすればよいですか?


この記事を参照してください。 stackoverflow.com/questions/14672234/...
アリsafaei

回答:


84

属性maxLinesはの最大の高さに対応し、EditText内側のテキスト行ではなく外側の境界を制御します。


それも私が思ったことです...入力された行を制限する方法はありますか、それともプログラムでバックエンドコードに制限する必要がありますか?
IndrekKõue、2011

入力した行を希望どおりに制限する簡単な方法はありません。コードで手動で行う必要があります。
Cedekasme 2011

3
開発者にとって、「maxLines」はeditTextで可能な最大行数を意味すると思います。特定の高さだけが必要な場合は、「線」を使用します。:-/
誰かどこか

241
<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あなたは正しいです!に設定してinputTypeから作業しましたtext。時間を節約してくれてありがとう:-)
by Jeevan

6
@byJeevan、私はいつもinputTypeに「テキスト」のデフォルト値があると思っていました。私が間違っていたと思います。
Noel Chew

2
TextがinputTypeに設定されているデフォルト値ではないことは非常に奇妙ですが、すばらしい回答です
Muhammed Refaat

9
maxLinesが1の場合のみ機能しますが、新しい行を追加することはできません
Daniel

68

これは、n行に制限するという一般的な問題を解決しません。EditTextを1行のテキストだけに制限する場合、これは非常に簡単です。
これはxmlファイルで設定できます。

android:singleLine="true"

またはプログラムで

editText.setSingleLine(true);

8
しかし、2行に制限したい場合はどうでしょうか?または3?そのためには、カスタム行リミッターを作成する必要があります...
IndrekKõue

4
私はそれを知っています。「これはn行に制限するという一般的な問題を解決しません」。私は1行に制限しようとしていて、より簡単な解決策を見つけている間に、ここで質問を読み終えました。EditTextを1行に制限し、「カスタム行リミッター」を実装しようとしている他のユーザーがここに来る可能性があると考えました。私の答えは、私が行ったのと同じ理由でこの質問を検索してしまう他のSOユーザーのためのものです。
ジェシーブラック

@IndrekKõue難しいことではありません。
Don Larynx、

10
singleLineは非推奨
Ali

1
editTextの属性singleLine = "true"は非推奨であり、7.0よりも大きいAndroidでデバイスを使用するとクラッシュします
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 2016

maxlines以上のテキストを貼り付けると機能しません。したがって、addTextChangedListenerを使用することをお勧めします。
Kuldeep Sakhiya 2016年

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、のEditTextはあなたが交換する「考える」ことabcdabcde理由インプットメソッドの理由で、。
ハンスイム

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 2015

"txtSpecialRequests"がEditTextコンテナーであることがわかりましたが、変数lastSpecialRequestsCursorPositionとspecialRequestsをどこに設定しますか?
drearypanoramic 2015年

もちろんこのメソッドの外では:) init lastSpecialRequestsCursorPosition = 0 and specialRequests = ""
Oscar Yuandinata '22 / 10/22

素晴らしい解決策!
マーカス

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

@AlanKley:editTextの行数を計算するには、テキスト変更イベントの前後に必要です。テキストを入力し続け、「改行」キーを押さないかのように、onKeyは起動されず、カーソルは自動的に次の行に移動しました。したがって、このような行を追跡するには、textWatcherが必要です。理解してもらえるといいのですが。
海賊

そうですか。その説明をありがとう。
AlanKley 2013

@AlanKley私の答えが役に立つと思うなら、投票してください。
海賊、2013年

public void afterTextChanged(Editable arg0){int lineCount = editText.getLineCount(); if(lineCount> numberOfLines){editText.setText(text); }}はStackOverflowExceptionをスローします...
desgraci 2014年


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



1

EditText1行に制限する別の方法は次のとおりです。

editText2.setTransformationMethod(new SingleLineTransformationMethod());

この変換方法を適用した後、Enterキーを押すとスペースが作成されることに注意してください。それでもTSの質問は満たされます。


新しい行を非表示にする良い方法です!ただし、値には「改行」の文字が残っています!!
グレゴリースタイン

1

あなたはあなたがあなたの行の数に応じてテキストを制限することができます

<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()は1つのオプションです。ゼロ以外の値が必要な場合は、ビューが測定されていることを確認してください。ソフトキーボードの場合、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を超えない場合にのみ、入力するたびに新しいテキストが文字列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に対するIndrekKõ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.