InputFilter 拦截过滤删除操作
Android 成长在于积累和分享
原文地址:https://www.jianshu.com/p/bf1168e46901
前言
InputFilter的使用目的是过滤,那么在某一些特殊情况下,除了要过滤不合理的输入操作,同样也要处理过滤不合理的删除操作,大部分人会下意识的认为使用return “” 即是不做任何操作,但其实对于删除来说,这样并不能将删除的操作过滤掉!
分析
首先,不能盲目看别人的结论,还是要结合源码去分析InputFilter是如何进行过滤的。
Source
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);
}
不必要的代码就不贴了,只看下filter方法的说明即可。其中有一句很关键的信息:Return the CharSequence that you would like to have placed there instead, including an empty string if appropriate, or null
to accept the original replacement.
说的已经很明白了,return的字符串使用来替换当前的操作的,这个时候如果返回空字符串,则表示使用空字符替换当前的输入,返回 null 则表示认同当前的操作,可以认为是不做任何处理。
一般情况下返回空字符的时候基本就相当于拦截了输入的操作,但是如果是删除的话,返回空字符则同等于使用空字符替换要删除的内容,这样的话就不能达到拦截删除的操作。
解决方式
那么想要使当前删除操作无效的话,该怎么去做呢 ?既然返回的字符串是用来替换当前的操作结果的,那么是否可以将其删除的内容获取到,并返回给父级处理,这样就等于把删除的内容去替换删除的操作。结果相当于什么都没能删除掉,本次删除无效,就可以达到拦截删除的目的了。
public class TestDeleteInputFilter implements InputFilter {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
// delete
if (source.length() == 0 && dend > dstart) {
// 通过添加已删除的内容达到不删除的效果
return dest.subSequence(dstart, dend);
}
return null;
}
}
测试效果
例子:字符操作只允许从尾端删除,不可以从中间删除。
public class TestDeleteInputFilter implements InputFilter {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
// delete
if (source.length() == 0 && dend > dstart) {
if (dend != dest.length()) {
// 非尾端删除
// 通过添加已删除的内容达到不删除的效果
return dest.subSequence(dstart, dend);
}
}
return null;
}
}
效果展示
总结
遇到问题的时候首先要明白其工作机制,多看下源码,也许答案就在源码中已经说明过。
上一篇: Mac彻底卸载搜狗输入法,看这一篇就够了
下一篇: SQLMap安装
推荐阅读