• 自定义可复制的textview


       最近准备写一款阅读相关的应用,希望内部的文字都可以实现完整的可复制性,这对于信息分享的而言至关重要。类似人人网客户端那样内部文字完全不可复制,信息只能在站内共享的方式让我很郁闷,所以我就想来实现一个类似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 cursorStart = -1;
    46 }
    47 return flag;
    48 }
    49
    50 @Override
    51 protected void onCreateContextMenu(ContextMenu menu) {
    52 super.onCreateContextMenu(menu);
    53 if (isInputMethodTarget()) {
    54 menu.removeItem(android.R.id.switchInputMethod);
    55 }
    56 }
    57
    58 // textview的点击捕捉
    59 // 如果双击textview选中了具体文字,则使cursor可见
    60 int cursorStart = -1;
    61
    62 @Override
    63 public boolean onTouchEvent(MotionEvent event) {
    64 boolean flag = super.onTouchEvent(event);
    65 if (event.getAction() == MotionEvent.ACTION_DOWN && hasSelection()) {
    66 if (cursorStart == -1) {// 由于点击选中文字后,再点击其他位置,第一次点击时显示的hasSelection依然为true,这样一来cursor会依然还在,为了避免这种情况,我这里多对selectionStart进行了一次验证
    67 setCursorVisible(true);
    68 cursorStart = getSelectionStart();
    69 } else {
    70 setCursorVisible(false);
    71 cursorStart = -1;
    72 }
    73 }
    74 return flag;
    75 }
    76
    77 // 当按返回键取消文字复制时,使cursor再次不可见
    78 @Override
    79 public boolean onKeyDown(int keyCode, KeyEvent event) {
    80 boolean flag = super.onKeyDown(keyCode, event);
    81
    82 setCursorVisible(false);
    83 cursorStart = -1;
    84 return flag;
    85 }
    86
    87 }
    88
    89 }



                                                原创手打,有问题可以邮件联系我:hisneric@gmail.com 希望大家一起学习共同提高 @x@



  • 相关阅读:
    Wannafly #4 F 线路规划
    PKUWC2018 随机算法
    noip模拟赛
    php 正则判断是否是手机号码 最新
    Onethink上传服务器后登录不了的问题
    【php中的curl】php中curl的详细解说
    50种网站引流量方式
    mysql ERROR 1045 (28000): 错误解决办法
    织梦DEDE分类信息实现联动筛选(支持多条件多级选项)解决方案
    dedecms新增联动类别后的使用方法
  • 原文地址:https://www.cnblogs.com/hisneric/p/2416741.html
Copyright © 2020-2023  润新知