http://mobile.51cto.com/android-224229.htm


Android开发:自由选择TextView的文字

2010-09-06 13:21 chroya Javaeye博客 我要评论(0) 字号: T | T

本文将介绍一下在Android下自由选择TextView的文字。用过EditText的都知道,EditText有个特点,ContextMenu提供了选择文字、复制、剪切等功能。如果直接就在view上选择文字,那样会更加方便。本文将教你如何自由选择TextView的文字。

AD:

我们介绍过一系列Android开发的教程,比如《如何实现TCP和UDP传输》、《在MyEclipse 8.6上搭建Android开发环境》,今天我们来介绍一下在Android下自由选择TextView的文字。

51CTO推荐专题:Android开发应用详解

用过EditText的都知道,EditText有个特点,当在里面长按的时候,会出现一个ContextMenu,提供了选择文字、复制、剪切等功能。如果不出现这个ContextMenu,直接就在view上选择文字,那样会更加方便。于是作者就研究了一下EditText和TextView的代码,然后将这个问题解决了。

网上很多资料都说,要选择一段文字,只需要用Selection.getSelectionStart()和Selection.getSelectionEnd()确定选择的文字的头和尾,然后加颜色就行。作者经过测试,发现这个结果导致误导了很多人,是行不通的。

我们来分析一下解决办法。

TextView是很多View的基类,如Button、EditText都是继承自他,所以EditText里面的代码很少。我们看一下EditText的源码,有一个Override的getDefaultEditable方法,看名字的意思是是否可编辑,这个方法直接返回true。还有一个getDefaultMovementMethod方法,它返回的是ArrowKeyMovementMethod.getInstance(),通过查看ArrowKeyMovementMethod的源码,基本确定这个方法就是弹出ContextMenu和轨迹球监听的“元凶”。

下面,我们自己做一个view来打造自己的EditText。

我取名TextPage,继承EditText,在里面覆盖getDefaultEditable和getDefaultMovementMethod。

Java代码

        
  1. @Override
  2. publicbooleangetDefaultEditable(){
  3. returnfalse;
  4. }
  5. @Override
  6. protectedMovementMethodgetDefaultMovementMethod(){
  7. returnnull;
  8. }

现在测试一下,发现长按没反应了,所料不错,就是getDefaultMovementMethod方法控制了ContextMenu。

看一下ArrowKeyMovementMethod的代码,里面提供了KeyEvent、轨迹球事件onTrackballEvent和touch事件onTouchEvent的处理。这些事件在何处调用的呢?我们看看TextView的onTouchEvent、onTrackballEvent和onKeyEvent方法里面就明白了,在这些事件回调中调用了ArrowKeyMovementMethod里面的这些方法。

还有个问题,ContextMenu在哪里触发的?这个问题,用过ContextMenu的都知道,view里面要使用ContextMenu,需要覆盖一个onCreateContextMenu方法,然后在里面创建ContextMenu的各个选项。在TextView里面找onCreateContextMenu,果然有,里面定义了选择、复制、粘贴等选项。

既然找到了这个,那么我们就可以进一步分析选择是如何做到的。

onCreateContextMenu只是创建菜单,那么菜单点击之后,触发了什么呢?

onCreateContextMenu里面定义了一个MenuHandler对象,然后作为参数传递给setOnMenuItemClickListener,找到MenuHandler,发现里面的onMenuItemClick返回的是onTextContextMenuItem函数,找到onTextContextMenuItem,OMG,终于找到点击menu触发的函数了。但是里面貌似没有关键的东西,选择的部分不在这里。那么,就应该在上面所说的那些事件里面了。

重点分析ArrowKeyMovementMethod的onTouchEvent方法。发现一个重要的方法getLayout(),然后获取一个Layout对象,通过x和y坐标知道当前字符串的offset位置。

那么,问题就可以完美的解决了。你可以点击任何地方然后拖动,释放之后,中间的文字就会被选中。

Java代码

        
  1. importandroid.content.Context;
  2. importandroid.graphics.Color;
  3. importandroid.text.Layout;
  4. importandroid.text.Selection;
  5. importandroid.view.ContextMenu;
  6. importandroid.view.Gravity;
  7. importandroid.view.MotionEvent;
  8. importandroid.widget.EditText;
  9. /**
  10. *@authorchroya
  11. */
  12. publicclassTextPageextendsEditText{
  13. privateintoff;//字符串的偏移值
  14. publicTextPage(Contextcontext){
  15. super(context);
  16. initialize();
  17. }
  18. privatevoidinitialize(){
  19. setGravity(Gravity.TOP);
  20. setBackgroundColor(Color.WHITE);
  21. }
  22. @Override
  23. protectedvoidonCreateContextMenu(ContextMenumenu){
  24. //不做任何处理,为了阻止长按的时候弹出上下文菜单
  25. }
  26. @Override
  27. publicbooleangetDefaultEditable(){
  28. returnfalse;
  29. }
  30. @Override
  31. publicbooleanonTouchEvent(MotionEventevent){
  32. intaction=event.getAction();
  33. Layoutlayout=getLayout();
  34. intline=0;
  35. switch(action){
  36. caseMotionEvent.ACTION_DOWN:
  37. line=layout.getLineForVertical(getScrollY()+(int)event.getY());
  38. off=layout.getOffsetForHorizontal(line,(int)event.getX());
  39. Selection.setSelection(getEditableText(),off);
  40. break;
  41. caseMotionEvent.ACTION_MOVE:
  42. caseMotionEvent.ACTION_UP:
  43. line=layout.getLineForVertical(getScrollY()+(int)event.getY());
  44. intcurOff=layout.getOffsetForHorizontal(line,(int)event.getX());
  45. Selection.setSelection(getEditableText(),off,curOff);
  46. break;
  47. }
  48. returntrue;
  49. }
  50. }

更多相关文章

  1. Android中最简单有效的Fragment全局管理器(全新实现方式)
  2. android hal层 c 堆栈打印方法
  3. Android(安卓)-- Activity,Fragment切换动画。
  4. Android简单实现仿微信选择图片以及拍照(PhotoPicker)
  5. Android应用防止模拟点击,防范抢红包类似插件的方法
  6. Android(安卓)设备 USB 通用调试驱动的安装方法
  7. Android(安卓)EventBus3.1.1从使用到源码解析
  8. Android面试题总结加强版(二)
  9. Android(安卓)图片压缩并保存的方法

随机推荐

  1. Android中RecyclerView实现横向滑动代码
  2. win7 下搭建基于jdk1.7 android开发环境
  3. android 快速开发(二)辅助类的使用:加快开发
  4. android 线条选择器
  5. android String 2
  6. 11. android 选项菜单(此处为icon menu)--
  7. AndroidStudio快捷键中文版
  8. android中SharedPreference的使用
  9. android应用程序的混淆打包(转)
  10. How to download sourcecode of android