/**
* Created by xiaoyee on 4/27/15
* 用户检测edittext输入状态,如果有内容,那么显示清空按钮,如果没有内容,则清空
* <p>
* 用法:
* <br/>edittext.addTextChangedListener(new InputWatcher(btnClear, etContent));
* <br/>{@link EditText#addTextChangedListener(TextWatcher)}
* </p>
*/
public class InputWatcher implements TextWatcher {
private static final String TAG = "InputWatcher" ;
private Button mBtnClear;
private EditText mEtContainer ;
/**
*
* @param btnClear 清空按钮 可以是button的子类
* @param etContainer edittext
*/
public InputWatcher(Button btnClear, EditText etContainer) {
if (btnClear == null || etContainer == null) {
throw new IllegalArgumentException("请确保btnClear和etContainer不为空");
}
this.mBtnClear = btnClear;
this.mEtContainer = etContainer;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!TextUtils.isEmpty(s)) {
if (mBtnClear != null) {
mBtnClear.setVisibility(View.VISIBLE);
mBtnClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mEtContainer != null) {
mEtContainer.getText().clear();
}
}
});
}
} else {
if (mBtnClear != null) {
mBtnClear.setVisibility(View.GONE);
}
}
}
@Override
public void afterTextChanged(Editable s) {
}
}
Note:需要在xml文件中自己定义EditText和清空用的Button
输入字数超过最大值时给予提示
/**
* Created by xiaoyee on 8/27/15
* 用法:
* <pre>
* mEditText.setFilters(new InputFilter[] { new LengthFilter(mMaxTextNum, activity) });
* </pre>
*/
public class LengthFilter implements InputFilter {
private int mMax;
private Activity mActivity;
final String mMsgToShow;
public LengthFilter(int max, Activity activity) {
mMax = max;
mActivity = activity;
mMsgToShow = "最多输入" + mMax + "个字哦";
}
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
int keep = mMax - (dest.length() - (dend - dstart));
if (keep <= 0) {
mActivity.runOnUiThread(
new Runnable() {
@Override
public void run() {
Toast.makeText(mActivity, mMsgToShow , Toast.LENGTH_LONG).show();
}
}
);
return "";
} else if (keep >= end - start) {
return null; // keep original
} else {
keep += start;
mActivity.runOnUiThread(
new Runnable() {
@Override
public void run() {
Toast.makeText(mActivity, mMsgToShow, Toast.LENGTH_LONG).show();
}
}
);
if (Character.isHighSurrogate(source.charAt(keep - 1))) {
--keep;
if (keep == start) {
return "";
}
}
return source.subSequence(start, keep);
}
}
}
参考代码如下:
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.text;
/**
* InputFilters can be attached to {@link Editable}s to constrain the
* changes that can be made to them.
*/
public interface InputFilter
{
/**
* This method is called when the buffer is going to replace the
* range <code>dstart … dend</code> of <code>dest</code>
* with the new text from the range <code>start … end</code>
* of <code>source</code>. Return the CharSequence that you would
* like to have placed there instead, including an empty string
* if appropriate, or <code>null</code> to accept the original
* replacement. Be careful to not to reject 0-length replacements,
* as this is what happens when you delete text. Also beware that
* you should not attempt to make any changes to <code>dest</code>
* from this method; you may only examine it for context.
*
* Note: If <var>source</var> is an instance of {@link Spanned} or
* {@link Spannable}, the span objects in the <var>source</var> should be
* copied into the filtered result (i.e. the non-null return value).
* {@link TextUtils#copySpansFrom} can be used for convenience.
*/
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend);
/**
* This filter will capitalize all the lower case letters that are added
* through edits.
*/
public static class AllCaps implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.isLowerCase(source.charAt(i))) {
char[] v = new char[end - start];
TextUtils.getChars(source, start, end, v, 0);
String s = new String(v).toUpperCase();
if (source instanceof Spanned) {
SpannableString sp = new SpannableString(s);
TextUtils.copySpansFrom((Spanned) source,
start, end, null, sp, 0);
return sp;
} else {
return s;
}
}
}
return null; // keep original
}
}
/**
* This filter will constrain edits not to make the length of the text
* greater than the specified length.
*/
public static class LengthFilter implements InputFilter {
private final int mMax;
public LengthFilter(int max) {
mMax = max;
}
public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
int dstart, int dend) {
int keep = mMax - (dest.length() - (dend - dstart));
if (keep <= 0) {
return "";
} else if (keep >= end - start) {
return null; // keep original
} else {
keep += start;
if (Character.isHighSurrogate(source.charAt(keep - 1))) {
--keep;
if (keep == start) {
return "";
}
}
return source.subSequence(start, keep);
}
}
/**
* @return the maximum length enforced by this input filter
*/
public int getMax() {
return mMax;
}
}
}