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