Android之输入框光标和Hint的位置

如图所示,要实现这一的需求,一般人的布局方式就是左边一button,右边一button,中间一个EditText,为了输入框的响应触摸范围更大往往不会把宽度设置为wrap_content,要么设置成match_parent/fill_parent要么给定个minWidth+wrap_content。
无论如何布局,gravity或layout_gravity都应是center才能达到需求所示。然而问题来了,如果gravity设置为了center,很不巧的是大部分手机(笔者某为竟然会自动纠正光标与hint的相对位置)实际运行效果是光标会位于hint的中间,要知道gravity会影响到光标所在位置,gravity为Left光标就在最左边,graity为right光标就在Hint的最右边,当然gravity为Center光标自然在hint的中间。

借图一张(来自万能的StackOverFlow,可惜万能的SOF也没给出答案)
遂冥思苦想各种弥救方法,主要有3个方案两个角度来解决。完美的角度是把光标位置想法设法调正,退而求其次的方法是显示hint(即输入框没有text)的时候隐藏光标。方案触发点有两个,一个是第一次没有任何text但设置了hint此时,入口应为onFocusChange方法;另一个是动态输入过程中清除了text,这个入口在onTextChange。
我总结出来有三个对策如下。
下策:当需要显示hint的时候把hint设置为空字符串,不需要显示hint的时候再把hint还原成需要设置的字符串。这种方法带来的效果就是,界面一打开能看见hint,当你一点击输入框开始输入就没有hint了,虽然此时光标可见,但还是有瑕疵,并且在onFocusChange方法里面设置hint会造成要点两次才会弹起输入法(具体原因尚未深究)。
中策:当需要显示hint的时候隐藏光标,一旦用户开始输入显示光标。这种效果类似第一种,一打开界面能看见hint,但看不到光标,你要开始输入才能看见。这也是有瑕疵的,当用户点了输入框(获得用户焦点)没有光标用户就会很郁闷不知道可不可以输入,缺乏光标的引导作用。
上策:那上策就是调整位置咯,其实也不是说能调整光标的位置,而是逆向思维把输入框的位置改变来适用光标所需要摆在的位置。这种方案实现起来有点复杂,改动量大。首先你EditTextd的宽度不能指定,minWidth不能由输入框来设置而要在它的parent容器设置最小宽度,所以它的width最好是wrap_content,并且设置一定的padding来保留一定用户触摸响应区域。然后EditText的Gravity还是Center,需要调整的就是它的LayoutGravity了,当用户有输入毫无疑问需要居中,当没有输入需要显示Hint时,那就要设置成Left了,然后计算出需要设置marginLeft距离。这个距离就是EditText(父容器的宽度-hint的宽度)/2,当然要获取LayoutWdth需要一定的技巧,获取hint的宽度更需要一点技巧。这样就能让光标位于hint的前面了,曲线救国吧。
干货来了。
android要获取宽高经常能拿到0这个值,这个一般有经验的都会在onWindowsFocus里去拿到,然后量字符串的像素,就需要你要用你显示hint的画笔去测量字符串,因为需要知道字体属性,比如字体、大小、粗细等。
直接上代码咯:
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (mSpaceWidth <= 0) mSpaceWidth = getWidth() - left.getWidth() - right.getWidth();
} @Override
public void onFocusChange(View v, boolean hasFocus) {
adjustCursorPosition(etInput.getText());
} @Override
public void afterTextChanged(Editable s) {
adjustCursorPosition(etInput.getText());
} private void adjustCursorPosition(CharSequence text){
if (!TextUtils.isEmpty(etInput.getHint())){
adjustGravityForCursor(text);//adjustCursorVisible(text);//adjustHintContent(hasFocus(),text);
}
} private void adjustGravityForCursor(CharSequence text) {
LayoutParams lp = (LayoutParams) etInput.getLayoutParams();
if (mSpaceWidth <= 0) mSpaceWidth = lp.width - left.getWidth() - right.getWidth();
if (!TextUtils.isEmpty(text)) {
etInput.setGravity(Gravity.CENTER);
lp.leftMargin = 0;
} else {
etInput.setGravity(Gravity.LEFT);
lp.leftMargin = (mSpaceWidth - measureText(etInput,mHint)) / 2;
}
etInput.setLayoutParams(lp);
} public int measureText(TextView textView, String text) {
TextPaint paint = textView.getPaint();
return (int) paint.measureText(text);
} private void adjustCursorVisible(CharSequence text){
etInput.setCursorVisible(!TextUtils.isEmpty(text));
} private void adjustHintContent(boolean hasFocus, CharSequence text){
if (TextUtils.isEmpty(text)) {
etInput.setHint(hasFocus ? "" : mHint);
}
}
Android之输入框光标和Hint的位置的更多相关文章
- android EditText获取光标位置并安插字符删除字符
android EditText获取光标位置并插入字符删除字符1.获取光标位置int index = editText.getSelectionStart(); 2.在光标处插入字符int index ...
- Android 设置EditText光标位置
Android中有很多可编辑的弹出框,其中有些是让我们来修改其中的字符,这时光标位置定位在哪里呢? 刚刚解了一个bug是关于这个光标的位置的,似乎Android原生中这种情况是把光标定位到字符串的最前 ...
- Android 设置EditText光标位置(转)
Android 设置EditText光标位置 最后 CharSequence text = edtTxt_my_account_edit_nickname.getText();if (text ins ...
- Android 设置EditText光标Curso颜色及粗细
在android的输入框里,如果要修改光标的颜色及粗细步骤如下两步即可搞定: 1.在资源文件drawable下新建一个光标控制color_cursor.xml <?xml version=&qu ...
- 在Android中动画移动一个View的位置,采用Scroller类实现Android动画之 View移动
在Android中动画移动一个View的位置,采用Scroller类实现 今天说最近自己遇到的一个问题,就是要用动画效果来移动一个VIew的位置. 这个具体的情况是,需要做一个SlidingMenu的 ...
- android EditText设置光标、边框和图标
控制边框形状,先在drawable中建一个xml文件:shape.xml <?xml version="1.0" encoding="utf-8"?> ...
- android EditText设置光标、边框和图标,以及限制输入
控制边框形状,先在drawable中建一个xml文件:shape.xml <?xml version="1.0" encoding="utf-8"?> ...
- Android 获取View在屏幕中的位置【转】
Android 获取View在屏幕中的位置 https://blog.csdn.net/lonely_fireworks/article/details/7849643
- Ubuntu终端常用的快捷键,光标移动到开始位置
光标操作,实用 Ctrl+a 光标移动到开始位置 Ctrl+e 光标移动到最末尾 删除 Ctrl+k 删除此处至末尾的所有内容 Ctrl+u 删除此处至开始的所有内容 删除单个 Ctrl+d 删除当前 ...
随机推荐
- 从源代码分析Android-Universal-Image-Loader的缓存处理机制
讲到缓存,平时流水线上的码农一定觉得这是一个高大上的东西.看过网上各种讲缓存原理的文章,总感觉那些文章讲的就是玩具,能用吗?这次我将带你一起看过UIL这个国内外大牛都追捧的图片缓存类库的缓存处理机制. ...
- 让你的CI跑起来-《持续集成》读书总结
持续集成已经被公认为极具价值的一项工程实践.在初始化一个项目时一个重要的任务就是搭建持续集成服务器,编写构建脚本.在我工作的所有项目中都引入了持续集成机制.它已经像氧气一样成为软件开发过程中的一项工程 ...
- Null Object模式
去除代码中的if(obj==null),或者try/catch语句.维持Code的一致性. Null对象,代表"什么也不做"的一个对象. 使Null对象称为一个匿名内部类确保了该类 ...
- 通过MSSQl作业定时执行批处理BAT文件
前言 有些时候,我们可能会需要定时执行一下批处理来达到一定的目的,比如Oracle数据库的定时备份,当然Oracle也可以通过Rman实现定时备份.我们大多数的时候是通过操作系统的计划任务实现定时执行 ...
- SAE部署django应用
最近自己动手实现了一个博客系统,使用基于python的web框架django,运行在SAE上.以下是遇到的问题,特总结如下: 1, SAE支持的django等第三方模块的版本如下: http://ww ...
- 阅读开发高手的代码 分享二则.NET开发框架的技巧
最近阅读了一套ERP开发框架的源代码,对开发框架的理解又深入一层,也为其将知识点运用的如此灵活而自叹不如. 郎咸平教授说,国际金融炒家对国际金融知识的理解与运用程序,是不可想像的.1997年的亚洲金融 ...
- linux之cp/scp命令+scp命令详解(转)
名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 说明:将一个档案拷贝至另一档案,或将数 ...
- H5小游戏的坑点小结
坑点: 1) iOS 9.1 的safari中,在onTouchBegan方法中调用cc.audioEngine.playEffect播放音效是没有效果的,如果在onTouchEnded调用则是正常的 ...
- jdk分析工具:jps和jstack
jps 用来查看基于HotSpot JVM里面所有进程的具体状态, 包括进程ID,进程启动的路径等等.与unix上的ps类似,用来显示本地有权限的java进程,可以查看本地运行着几个java程序,并显 ...
- ASP怎么解除文件上传200kb限制
第一步:修改IIS设置,允许直接编辑配置数据库.打开,Internet信息服务第二步:先在服务里关闭iis admin service服务,找到windows\system32\inetsrv\下的m ...