EditText的实时字符数


101

我想知道对Android编辑文本框进行实时字符计数的最佳方法是什么。我正在看这个,但似乎没有任何意义。

为了描述问题,我有一个EditText,我试图将字符限制为150个。我可以使用输入过滤器来做到这一点,但是我想在文本框的正下方显示用户输入的字符数(几乎例如堆栈溢出正在执行)。

如果有人可以编写一小段示例代码或向正确的方向指点我,我将不胜感激。

Answers:


153

您可以使用TextWatcher查看何时更改了文字

private TextView mTextView;
private EditText mEditText;
private final TextWatcher mTextEditorWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {
           //This sets a textview to the current length
           mTextView.setText(String.valueOf(s.length()));
        }

        public void afterTextChanged(Editable s) {
        }
};

您使用以下方法将TextWatcher设置为edittext

mEditText.addTextChangedListener(mTextEditorWatcher);

5
尝试了这个,效果很好!应该选择为正确答案!
Patrick Boos

2
在文本框的右下角说增加计数的最佳方法是什么。扩展编辑文本并手动绘制字符串?
2012年

1
谢谢,我也知道了,但是在输入文本时如何以相反的顺序倒数,例如150,149,148,147...。
vinay Maneti

6
它通过替换为mTextView.setText(String.valueOf(150-s.length()))来解决。代替mTextView.setText(String.valueOf(s.length()));
vinay Maneti

我的问题类似于@Bear有。我需要在编辑文本的正下方显示此倒计时文本。任何人都可以在此参考资料中分享任何东西。谢谢。
Suresh Sharma 2015年

107

您可以使用SupportLibrary v23.1中引入的TextInputLayout包装器(用于EditText)从xml本身进行字符计数

只需用TextInputLayout包装EditText并将CounterEnabled设置为true并设置counterMaxLength。

<android.support.design.widget.TextInputLayout
    android:id="@+id/textContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:counterEnabled="true"
    app:counterMaxLength="20"
    >
    <EditText
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Text Hint"
        />
</android.support.design.widget.TextInputLayout>

你会得到这样一个重大的影响

您可以使用counterOverflowTextAppearancecounterTextAppearance来设置计数器样式。

编辑

来自Android文档。

TextInputEditText提供一流用作此布局的孩子。使用TextInputEditText可以使TextInputLayout更好地控制任何文本输入的视觉效果。用法示例如下:

     <android.support.design.widget.TextInputLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">

     <android.support.design.widget.TextInputEditText
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:hint="@string/form_username"/>

 </android.support.design.widget.TextInputLayout>

TextInputLayout TextInputEditText


3
这正是我在寻找的内容:)干净的支持库显示。谢谢
VPZ 2015年

3
应该是已接受的答案!我完全错过了那些属性!
sud007'1

24

您可以使用以下方法TextInputLayout和兼容库:

app:counterEnabled="true"
app:counterMaxLength="420"

并完成:

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:counterEnabled="true"
    app:counterMaxLength="420">

    <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:maxLength="420" />

</android.support.design.widget.TextInputLayout>

很好,这对我有用,但是如何改变柜台的颜色?
埃里希·加西亚

14

在xml中为editText添加此属性

    android:maxLength="80"

在Java中添加此侦听器

  ed_caption.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) {
            tv_counter.setText(80 - s.toString().length() + "/80");

        }
    });

7

它非常简单,请按照以下说明进行操作:

====将它们添加到您的导入中===

import android.text.Editable;
import android.text.TextWatcher;

=====定义此=====

private TextView sms_count;

==========内部创建=====

sms_count = (TextView) findViewById(R.id.textView2);


final TextWatcher txwatcher = new TextWatcher() {
   public void beforeTextChanged(CharSequence s, int start, int count, int after) {
   }

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

      sms_count.setText(String.valueOf(s.length()));
   }

   public void afterTextChanged(Editable s) {
   }
};

sms_message.addTextChangedListener(txwatcher);

5
    You can use TextWatcher class to see text has changed and how much number of character remains.Here i have set counter of 140 characters.

    EditText typeMessageToPost;
    TextView number_of_character;
public void onCreate(Bundle savedBundleInstance) {
        super.onCreate(savedBundleInstance);
setContentView(R.layout.post_activity);
typeMessageToPost.addTextChangedListener(mTextEditorWatcher);
}
private final TextWatcher mTextEditorWatcher=new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            number_of_character.setText(String.valueOf(140-s.length()));
        }
    };

谢谢@RavishSharma :)感谢您的评论。
拉娜·普拉塔普·辛格

4

只需TextInputLayout在XML文件中设置以下两行即可:

app:counterEnabled="true"
app:counterMaxLength="200"

太不知道了。将Edittext包装到TextInputLayout中似乎总是更好的解决方案。
Stefan Sprenger'7

3

该解决方案使用Kotlin并显示剩余的字符数。另外,如果当前字符数超过了限制50,则文本颜色将变为红色。

科特林

private val mTitleTextWatcher = object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}

    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
        if(YOUR_EDIT_TEXT_ID.text.toString().trim().length < 51){
            YOUR_CHAR_LEFT_TEXTVIEW_ID.text = (50 - YOUR_EDIT_TEXT_ID.text.toString().trim().length).toString()
            YOUR_CHAR_LEFT_TEXTVIEW_ID.setTextColor(Color.BLACK)
        }
        else{
            YOUR_CHAR_LEFT_TEXTVIEW_ID.text = "0"
            YOUR_CHAR_LEFT_TEXTVIEW_ID.setTextColor(Color.RED)
        }
    }

    override fun afterTextChanged(s: Editable) {}
}

另外,别忘了将添加TextWatcher到您的EditText

YOUR_EDIT_TEXT_ID.addTextChangedListener(mTitleTextWatcher)

3

您可以将计数器添加到包装在TextInputLayout中的TextInputEditText中。如您在示例中所看到的,counterEnabled启用此功能并counterMaxLengh为其定义字符数。

<com.google.android.material.textfield.TextInputLayout
        android:id="@+id/til_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:counterEnabled="true"
        app:counterMaxLength="50">
    <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/et_title"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>

1

我遇到了同样的问题,我尝试了卡梅伦的方法。它可以工作,但是有一个小错误:如果用户使用复制和粘贴,则无法计算字符数。因此,我建议在文本更改后执行以下操作:

    private final TextWatcher mTextEditorWatcher = new TextWatcher() {
         public void beforeTextChanged(CharSequence s, int start, int count, int after) {

         }

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

         }

          public void afterTextChanged(Editable s) {
             //This sets a textview to the current length
             mTextView.setText(String.valueOf(s.length()));
         }
    };


0

尝试做这样的事情。

与获取CharSequence.length相比,此解决方案可能更高效。每次您点击软键盘时,事件就会触发。因此,如果您进行长度计算,则每次都会计算CharSequence,如果您开始使用大型CharSequnces,这可能会变慢。文本更改上的事件侦听器添加前后计数。这对于增量和减量值非常有效

@Override
        public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
            int tick = start + after;
            if(tick < mMessageMax) {
                int remaining = mMessageMax - tick;
                ((TextView)findViewById(R.id.contact_us_chars)).setText(String.valueOf(remaining));
            }
        }

这是效果,TextWatcher是最好的方法
Naveed Ahmad

0

试试这个

private TextWatcher textWatcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
        editText.post(new Runnable() {
            @Override
            public void run() {
                if (length < 100) {
                    if (count > 0 && after <= 0)/*remove emoij*/ {
                        length--;
                    } else if (count > after)/*remove text*/ {
                        length--;
                    } else if (count == 0 && after > 1)/*emoij*/ {
                        ++length;
                    } else if (count == 0 && after == 1)/*Text*/ {
                        ++length;
                    } else if (count > 0 && after > 1) {
                        ++length;
                    }
                    if (s.length() <= 0)
                        length = 0;
                    Log.w("MainActivity", " Length: " + length);
                } else {
                    if (count > 0 && after <= 0)/*remove emoij*/ {
                        length--;
                    } else if (count > after)/*remove text*/ {
                        length--;
                    }
                    Log.w("MainActivity", " Length: " + length);
                }

                if (length == 100) {
                    editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(s.length())});
                } else {
                    editText.setFilters(new InputFilter[]{});
                }
            }
        });
    }

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

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
};

`


0

思路清晰;

abstract class CharacterWatcher : TextWatcher {
    override fun afterTextChanged(text: Editable?) {
        afterCharacterChanged(text?.lastOrNull(), text?.length)
    }

    override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, before: Int) {}

    override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) {}

    abstract fun afterCharacterChanged(char: Char?, count: Int?)
}



 editText.addTextChangedListener(new CharacterWatcher() {
            @Override
            public void afterCharacterChanged(@Nullable Character character, @Nullable Integer count) {
                action()
            }
        });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.