Android开发:自由选择EditText的文字
来源:互联网 发布:台湾海关数据 编辑:程序博客网 时间:2024/06/10 14:51
用过EditText的都知道,EditText有个特点,当在里面长按的时候,会出现一个ContextMenu,提供了选择文字、复制、剪切等功能。如果不出现这个ContextMenu,直接就在view上选择文字,那样会更加方便。于是作者就研究了一下EditText和TextView的代码,然后将这个问题解决了。
网上很多资料都说,要选择一段文字,只需要用Selection.getSelectionStart()和Selection.getSelectionEnd()确定选择的文字的头和尾,然后加颜色就行。作者经过测试,发现这个结果导致误导了很多人,是行不通的。
我们来分析一下解决办法。
TextView是很多View的基类,如Button、EditText都是继承自他,所以EditText里面的代码很少。我们看一下EditText的源码,有一个Override的getDefaultEditable方法,看名字的意思是是否可编辑,这个方法直接返回true。还有一个getDefaultMovementMethod
下面,我们自己做一个view来打造自己的EditText。
我取名TextPage,继承EditText,在里面覆盖getDefaultEditable和getDefaultMovementMethod
Java代码
- @Override
- public
boolean getDefaultEditable() { -
return false; - }
- @Override
- protected
MovementMethod getDefaultMovementMethod () { -
return null; - }
现在测试一下,发现长按没反应了,所料不错,就是getDefaultMovementMethod
看一下ArrowKeyMovementMethod的代码,里面提供了KeyEvent、轨迹球事件onTrackballEvent和touch事件onTouchEvent的处理。这些事件在何处调用的呢?我们看看TextView的onTouchEvent、onTrackballEvent和onKeyEvent方法里面就明白了,在这些事件回调中调用了ArrowKeyMovementMethod里面的这些方法。
还有个问题,ContextMenu在哪里触发的?这个问题,用过ContextMenu的都知道,view里面要使用ContextMenu,需要覆盖一个onCreateContextMenu方法,然后在里面创建ContextMenu的各个选项。在TextView里面找onCreateContextMenu,果然有,里面定义了选择、复制、粘贴等选项。
既然找到了这个,那么我们就可以进一步分析选择是如何做到的。
onCreateContextMenu只是创建菜单,那么菜单点击之后,触发了什么呢?
onCreateContextMenu里面定义了一个MenuHandler对象,然后作为参数传递给setOnMenuItemClickListen
重点分析ArrowKeyMovementMethod的onTouchEvent方法。发现一个重要的方法getLayout(),然后获取一个Layout对象,通过x和y坐标知道当前字符串的offset位置。
那么,问题就可以完美的解决了。你可以点击任何地方然后拖动,释放之后,中间的文字就会被选中。
Java代码
- import
android.content.Context; - import
android.graphics.Color; - import
android.text.Layout; - import
android.text.Selection; - import
android.view.ContextMenu; - import
android.view.Gravity; - import
android.view.MotionEvent; - import
android.widget.EditText; -
-
- public
class TextPage extends EditText { -
private int off; //字符串的偏移值 -
-
public TextPage(Context context) { -
super(context); -
initialize(); -
} -
-
private void initialize() { -
setGravity(Gravity.TOP); -
setBackgroundColor(Color.WHITE); -
} -
-
@Override -
protected void onCreateContextMenu(ContextMenu menu) { -
//不做任何处理,为了阻止长按的时候弹出上下文菜单 -
} -
-
@Override -
public boolean getDefaultEditable() { -
return false; -
} -
-
@Override -
public boolean onTouchEvent(MotionEvent event) { -
int = event.getAction(); -
Layout = getLayout(); -
int = 0; -
switch(action) { -
case MotionEvent.ACTION_DOWN: -
= layout.getLineForVertical(getScrollY()+(int)event.getY()); -
= layout.getOffsetForHorizontal(line,(int)event.getX()); -
Selection.setSelection(getEditableText(), off); -
break; -
case MotionEvent.ACTION_MOVE: -
case MotionEvent.ACTION_UP: -
= layout.getLineForVertical(getScrollY()+(int)event.getY()); -
int = layout.getOffsetForHorizontal(line,(int)event.getX()); -
Selection.setSelection(getEditableText(), off, curOff); -
break; -
} -
return true; -
} - }
- Android开发:自由选择EditText的文字
- Android开发:自由选择TextView的文字
- Android开发:自由选择TextView的文字
- Android开发:自由选择TextView的文字
- Android开发:自由选择TextView的文字
- Android开发:自由选择TextView的文字
- Android自由选择TextView的文字
- Android自由选择TextView的文字
- Android自由选择TextView的文字
- Android自由选择TextView的文字
- Android自由选择TextView的文字
- Android自由选择TextView的文字
- Android自由选择TextView的文字
- Android自由选择TextView的文字
- 自由选择TextView的文字
- Android 监听EditText输入文字的字数
- Android左边有固定文字的EditText
- Android 开发(如何动态设置EditText输入的文字为密码形式)
- 枚举(穷举)算法
- 事务的定义,事务的作用以及Spring事务原理
- android日志操作备份
- 恢复数据库得到webshell
- oracle正则表达式
- Android开发:自由选择EditText的文字
- 没有硬件,我们就玩模拟的——android4.0编译过程
- RHEL安装后
- Cortex-M3 Core之指令
- word中 英文输入状态下 逗号的输入
- 1125
- 使用coredata导致的版本更新后程序crash的问题
- c# 反射 遍历实体的所有字段,ObjectDumper类实现
- 黑马程序员--网络编程