相关资讯
本类常用软件
-
福建农村信用社手机银行客户端下载下载量:584204
-
Windows优化大师下载量:416898
-
90美女秀(视频聊天软件)下载量:366961
-
广西农村信用社手机银行客户端下载下载量:365699
-
快播手机版下载量:325855
最近准备写一款阅读相关的应用,希望内部的文字都可以实现完整的可复制性,这对于信息分享的而言至关重要。类似人人网客户端那样内部文字完全不可复制,信息只能在站内共享的方式让我很郁闷,所以我就想来实现一个类似uc网页页面内容皆可复制的textview。
在仔细看了一段时间textview和edittext的代码之后,我发现其实如果要求不高的话,我们完全可以在edittext的基础上来实现一个符合我所述要求的textview。具体实现过程不难,有两大主要问题点。
首先 ,edittext已经很好的实现了相关文本复制的操作,但是我希望不能在其内部输入文字,不能对内部的文字进行删减。
其次,我们需要解决edittext游标cursor的问题,使其在我们需要的时候出现,不需要的时候gone去一边。
第一个问题很简单,我们只需要在应用到该edittext的地方属性android: seteditable=”false”就可以了。关键难点在于第二点,我们如果想当然地认为只要设置setCursorVisible=”false”就能满足需求的话就大错特错了。我们需要清晰地了解cursor什么时候会出现,什么时候不会消失。
实际测试过程我发现edittext中的代码量很少,大部分的功能其实都在textview中被实现了,而导致,导致我们在长按edittext时弹出复制剪切选择框的关键方法如下:
View Code
1 @Override
2 protected MovementMethod getDefaultMovementMethod() {
3 // TODO Auto-generated method stub
4 return super.getDefaultMovementMethod();
5 }
树藤摸瓜,我们可以看到与复制相关的几个关键类是:
ArrowKeyMovementMethod和Selection。
当然纯粹为了实现我这儿的功能的话这两个类都暂时不用去动。
我们只需要重写几个edittext里的方法就可以,具体代码如下:
View Code
1 package com.hebin.activity;
2 3 import android.content.Context;
4 import android.text.Selection;
5 import android.text.method.MovementMethod;
6 import android.util.AttributeSet;
7 import android.view.ContextMenu;
8 import android.view.KeyEvent;
9 import android.view.MotionEvent;
10 import android.widget.EditText;
11 12 /**
13 * @author heb
14 * @class_name MyTextView.java
15 * @date 2012-3-22
16 */
17 public class MyTextView extends EditText {
18 19 public MyTextView(Context context, AttributeSet attrs) {
20 super(context, attrs);
21 }
22 23 // 长按弹出文本选择框menu的关键方法:可以选择复制、剪切等等功能,视该textview的具体实现而定
24 // 如果希望不弹出这个menu界面,只要把这个方法返回空就ok
25 @Override
26 protected MovementMethod getDefaultMovementMethod() {
27 // TODO Auto-generated method stub
28 return super.getDefaultMovementMethod();
29 }
30 31 // 点击menu中的选定item的具体处理方法,捕捉点击文本复制、剪切等按钮的动作
32 // 如果要在点击复制按钮之后取消该textview的cursor可见性的具体监听写在这里
33 @Override
34 public boolean onTextContextMenuItem(int id) {
35 setCursorVisible(true);
36 boolean flag;
37 if (id != android.R.id.switchInputMethod) {
38 flag = super.onTextContextMenuItem(id);
39 } else {
40 setCursorVisible(false);
41 return false;
42 }
43 if (id == android.R.id.copy) {
44 setCursorVisible(false);
45 }
46 return flag;
47 }
48 49 @Override
50 protected void onCreateContextMenu(ContextMenu menu) {
51 super.onCreateContextMenu(menu);
52 if (isInputMethodTarget()) {
53 menu.removeItem(android.R.id.switchInputMethod);
54 }
55 }
56 57 // textview的点击捕捉
58 // 如果双击textview选中了具体文字,则使cursor可见
59 int cursorStart = -1;
60 61 @Override
62 public boolean onTouchEvent(MotionEvent event) {
63 boolean flag = super.onTouchEvent(event);
64 if (event.getAction() == MotionEvent.ACTION_DOWN && hasSelection()) {
65 if (cursorStart == -1) {// 由于点击选中文字后,再点击其他位置,第一次点击时显示的hasSelection依然为true,这样一来cursor会依然还在,为了避免这种情况,我这里多对selectionStart进行了一次验证66
setCursorVisible(true);
67 cursorStart = getSelectionStart();
68 } else {
69 setCursorVisible(false);
70 cursorStart = -1;
71 }
72 }
73 return flag;
74 }75
76 // 当按返回键取消文字复制时,使cursor再次不可见
77 @Override
78 public boolean onKeyDown(int keyCode, KeyEvent event) {
79 boolean flag = super.onKeyDown(keyCode, event);
80 if (!hasSelection()) {
81 setCursorVisible(false);
82 cursorStart = -1;
83 }
84 return flag;
85 }
86 87 }
1 package com.hebin.activity;
2 3 import android.content.Context;
4 import android.text.Selection;
5 import android.text.method.MovementMethod;
6 import android.util.AttributeSet;
7 import android.view.ContextMenu;
8 import android.view.KeyEvent;
9 import android.view.MotionEvent;
10 import android.widget.EditText;
11 12 /**
13 * @author heb
14 * @class_name MyTextView.java
15 * @date 2012-3-22
16 */
17 public class MyTextView extends EditText {
18 19 public MyTextView(Context context, AttributeSet attrs) {
20 super(context, attrs);
21 }
22 23 //长按弹出文本选择框menu的关键方法:可以选择复制、剪切等等功能,视该textview的具体实现而定
24 //如果希望不弹出这个menu界面,只要把这个方法返回空就ok
25 @Override
26 protected MovementMethod getDefaultMovementMethod() {
27 // TODO Auto-generated method stub
28 return super.getDefaultMovementMethod();
29 }
30 //点击menu中的选定item的具体处理方法,捕捉点击文本复制、剪切等按钮的动作
31 //如果要在点击复制按钮之后取消该textview的cursor可见性的具体监听写在这里
32 @Override
33 public boolean onTextContextMenuItem(int id) {
34 setCursorVisible(true);
35 boolean flag;
36 if(id!=android.R.id.switchInputMethod){
37 flag =super.onTextContextMenuItem(id);
38 }else{
39 setCursorVisible(false);
40 return false;
41 }
42 if(id==android.R.id.copy){
43 setCursorVisible(false);
44 }
45 return flag;
46 }
47 @Override
48 protected void onCreateContextMenu(ContextMenu menu) {
49 super.onCreateContextMenu(menu);
50 if (isInputMethodTarget()) {
51 menu.removeItem(android.R.id.switchInputMethod);
52 }
53 }
54 55 //textview的点击捕捉
56 //如果双击textview选中了具体文字,则使cursor可见
57 int cursorStart=-1;
58 @Override
59 public boolean onTouchEvent(MotionEvent event) {
60 boolean flag = super.onTouchEvent(event);
61 if(event.getAction()==MotionEvent.ACTION_DOWN&&hasSelection()){
62 if(cursorStart==-1){//由于点击选中文字后,再点击其他位置,第一次点击时显示的hasSelection依然为true,这样一来cursor会依然还在,为了避免这种情况,我这里多对selectionStart进行了一次验证63
setCursorVisible(true);
64 cursorStart=getSelectionStart();
65 }else{
66 setCursorVisible(false);
67 cursorStart=-1;
68 }
69 }
70 return flag;
71 }
72 //当按返回键取消文字复制时,使cursor再次不可见
73 @Override
74 public boolean onKeyDown(int keyCode, KeyEvent event) {
75 boolean flag =super.onKeyDown(keyCode, event);
76 if(!hasSelection()){
77 setCursorVisible(false);
78 }
79 return flag;
80 }81
82 83 }