web-dev-qa-db-fra.com

EditText maxLines ne fonctionne pas - l'utilisateur peut toujours entrer plus de lignes que celles définies

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

L'utilisateur peut entrer plus de 5 lignes en appuyant sur la touche entrée/ligne suivante. Comment limiter l'entrée utilisateur à un nombre fixe de lignes avec EditText?

97
Indrek Kõue

L'attribut maxLines correspond à la hauteur maximale de EditText, il contrôle les limites extérieures et non les lignes de texte intérieures. 

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

Vous devez juste vous assurer que vous avez défini l'attribut "inputType". Cela ne fonctionne pas sans cette ligne.

Android:inputType="text"
187
Noel Chew

Cela ne résout pas le problème général de la limitation à n lignes. Si vous souhaitez limiter votre EditText à une seule ligne de texte, cela peut être très simple.
Vous pouvez définir ceci dans le fichier XML.

Android:singleLine="true"

ou par programmation

editText.setSingleLine(true);
62
Jesse Black

@ Cedekasem vous avez raison, il n'y a pas de "limiteur de rangée" intégré. Mais j'en ai construit un moi-même, donc si vous êtes intéressé, le code est ci-dessous. À votre santé.

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

J'ai fait quelque chose que vous recherchiez. Voici ma classe LimitedEditText.

Caractéristiques:

  • vous pouvez limiter le nombre de lignes dans votre composant LimitedEditText
  • vous pouvez limiter le nombre de caractères dans votre composant LimitedEditText
  • si vous dépassez la limite de caractères ou de lignes quelque part au milieu du texte, le curseur
    ne vous mènera pas à la fin - il restera où vous avez été.

Je désactive l'écouteur, car chaque appel de la méthode setText() appellera récursivement ces 3 méthodes de rappel au cas où l'utilisateur dépasserait la limite de caractères ou de lignes.

Code:

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

J'ai fait une solution plus simple pour cela: 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);
        }
    });

Vous pouvez modifier la valeur de 3 dans txtSpecialRequests.getLineCount() > 3 en fonction de vos besoins.

10
Oscar Yuandinata

Voici un filtre d'entrée qui limite les lignes autorisées dans 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;
  }
}

Pour l'ajouter à EditText:

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

C'est ce que j'ai utilisé dans mon projet:

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

Et cela a fonctionné dans tous les scénarios

4
Pirate

c'est une approche. Peut aider quelqu'un.

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

Une autre façon de limiter votre EditText à une ligne est la suivante:

editText2.setTransformationMethod(new SingleLineTransformationMethod());

Notez qu'après avoir appliqué cette méthode de transformation, la touche Entrée crée des espaces lorsque vous appuyez dessus. Cela répond toujours à la question de TS.

1
giorgos29cm

Vous pouvez limiter votre texte en fonction de votre nombre de lignes, je dis environ 37 alphabets sur une ligne.

<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

Pour limiter le nombre de caractères, nous pouvons simplement utiliser la propriété maxLength de EditText car elle ne permettra pas à l'utilisateur de saisir plus de caractères.

0
Pirate

La solution la plus simple:

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 () est une option; si vous voulez des valeurs non nulles, assurez-vous que votre vue est mesurée. Pour le clavier logiciel, onKeyListener ne fonctionnera pas, vous devez donc ajouter AddTextChangedListener () qui suivra les modifications de texte à mesure que vous tapez. Dès que vous avez suffisamment de lignes dans ses rappels, faites ce que vous voulez: limitez les caractères avec getText (), setText () ou quelque chose de plus sophistiqué. Vous pouvez même limiter le nombre de caractères à l'aide d'un filtre. 

Une autre option consiste à surveiller la taille du texte avec getLineBounds (). Cela va interagir avec le texte gravité/paddign alors soyez prudent. 

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