针对EditText 的相关知识点整理一下,主要有EditText的相关属性,EditText的自定义VIew方面以及连带的其他知识点;一为EditText的相关属性及连带知识点,后面写写自定义view继承EditText, 比如密码输入框(带删除,明文暗文按钮),更强大的autoCompletTextView.
监听布局变化
场景:对于一些登陆界面,在输入密码和账号的时候,当软键盘弹出来的时候,需要把密码账号输入框向上移动?让用户输入的位置始终位于屏幕中间往上一点的位置;
插入图片:
思路
通过监听跟布局变化 rootView.getViewTreeObserver().addOnGlobalLayoutListener 来实现,然后布局最外面通过scollview包裹起来,清单文件中的activity的加上 android:windowSoftInputMode="adjustResize" 。
步骤如下:
先在布局加载完后,用异步获取刚开始软键盘没有弹出来的时候高度。在动态监听布局的变化并作出相应的改变;
其核心代码如下:
异步获取开始控件坐标:
new Handler().post(new Runnable() {
@Override
public void run() {
mInputHeightInScreen = getViewYLocationInScreeen(mAccountNameEdt);
LogUtil.debugLog(TAG, "initWidget: " + mInputHeightInScreen);
}
});
对用户产生交互后的布局进行监听:
// 这里的rootView 可以是最外层布局scrollView 或者 setContentView 中的view
// 以及那个fragment中的那个inflater 打包的view;
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
int mainInvisibleHeight = rootView.getRootView().getHeight() - rect.bottom;
int screenHeight = rootView.getRootView().getHeight();
if (mainInvisibleHeight > screenHeight / 4){
int[] location = new int[2];
mSubmitBtn.getLocationInWindow(location);
final int scrollHeight = location[1] + mSubmitBtn.getHeight() - rect.bottom;
LogUtil.debugLog(TAG, "location[1]为:" + location[1] + ",scrollHeight为" + scrollHeight + ", rect.bottom为" + rect.bottom + "mainInvisibleHeight:" + mainInvisibleHeight);
if (mAccountNameEdt.isFocused()){
mScrolView.scrollTo(0 , getViewYLocationInScreeen(mAccountNameEdt) - mInputHeightInScreen );
} else if (mFirstNameEdt.isFocused()){
mScrolView.scrollTo(0 , 150);
}else if (mLastNameEdt.isFocused()){
mScrolView.scrollTo(0 , 300);
}else if (mAccountPasswordEdt.isFocused()){
new Handler().post(new Runnable() {
@Override
public void run() {
if (scrollHeight != 0){
mScrolView.scrollTo(0, 400);
}
}
});
}
}else {
mScrolView.scrollTo(0, 0);
}
}
});
// 这个是view的坐标获取方法
private int getViewYLocationInScreeen(View view){
int[] location = new int[2];
view.getLocationInWindow(location);
return location[1];
}
这里的移动的距离150, 300也是大致估算的,有时候布局也显得不怎么好看。但是这里不能进行计算了在进行移动距离,会出一些问题,现在忘了什么问题了。
digts 和 inputType 冲突
当digts在xml运用时,如果在代码中设置 inputType的话,会使digts失效,具体的原因其他网友有分析过,大致就是会覆盖之类的,
//显示密码:
mPW.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
//隐藏密码:
mPW.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
用其他的方式去显示和隐藏密码:
显示密码:
mPW.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
隐藏密码:
mPW.setTransformationMethod(PasswordTransformationMethod.getInstance());
digts的应用:
digts
在editText 中经常会限制输入,特别是一些字符相关的,个人认为有InputFilter 、正则表达式、 digts等方式,digts其实 比较好用,先说digts吧,由于digts是采用xml中属性形式,并且需要一个个打出相应的字符表示可以输入的;这样会有些问题:一些特殊字符的输入,字符需要穷举出来,比如一些特殊字符在xml中有些限制,一些常规字符是可以直接键盘打出来,像 < \ > ? | ; 等等这些常规字符,像 三角符合 △,π,· 这些特殊符合无法直接写在xml中,需要用相应的ASCII 码表示(在线转换工具),通过这个工具把特殊字符对应的ASCII码找到,然后加上 "&#" 及末尾的“;” ,如下所示:
< //代表 <
£ //代表 £
<string name="common_password_et_content">0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-/:;()>€$@"'!?,._\|~=+*^%#}{][-×÷π√|`~°&<£¥¢¶©®•</string>
或者可以查询别人已经列好的ASCII码对应表 对应表;
InputFilter 应用
android api 中有 LengthFilter ,实现此类要实现 filter 方法,比如实现禁止空字符输入的filter 代码为:
//禁止输入空格 filter
InputFilter filter = new InputFilter() {
@Override
public CharSequence filter(CharSequence charSequence, int i, int i1, Spanned spanned, int i2, int i3) {
if (charSequence.equals(" "))
return "";
return null;
}
};
mAccountEt.setFilters(new InputFilter[] {filter , new InputFilter.LengthFilter(20)});
这个InputFilter 可以和正则表达式结合使用,比如一些常用的正则表达式,中文字符unicode编码开始和结束分别对应着 “\u4e00”和“\u9fa5”;
//允许输入小写字母、大写字母、数字、中划线、下划线、@符号、空格、中文
public static final String REX_NAME = "[^a-zA-Z0-9\\-\\_\\@\\s\\u4e00-\\u9fa5]";
public static final String REX_PASSWORD = "[^a-zA-Z0-9\\!\\#\\$\\%\\(\\)\\*\\+\\,\\-\\.\\/\\<\\=" + "\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~]*";
后面再专门对正则表达式的应用专门写一篇博客,由于这方面的应用场景还是挺多的,而且知识点也不少。