登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

android WebView 长按自由复制文字,进入文字选择模式 [复制链接]

2017-9-13 11:41
kengsirLi 阅读:163 评论:0 赞:0
Tag:  

长按WebView系统默认进入文字选择默认,但如果想实现先长按菜单显示菜单同能菜单选项来判断是否进行的进入自由复制文本文字选择的操作就不知道该怎么办了。

长按WebView显示弹出菜单,可怎么才在能实现点击菜单选择进入自由复制文本模式呢?在网上翻了个遍,都不怎么如意,纠结了几日,下午偷懒睡了一觉突然就想到了Instrumentation模拟长按操作触发WebView默认的显示复制菜单


先实现模拟长按操作实现类

  1. /** 
  2.  * 模拟点击事件和长按事件 
  3.  * 
  4.  */  
  5.   
  6. public class TouchEventRunnable implements Runnable {  
  7.     private int x;  
  8.     private int y;  
  9.   
  10.     private boolean isLongPress;  
  11.   
  12.     public TouchEventRunnable(int x, int y) {  
  13.         this.x = x;  
  14.         this.y = y;  
  15.     }  
  16.     public TouchEventRunnable(int x, int y, boolean isLongPress) {  
  17.         this.x = x;  
  18.         this.y = y;  
  19.         this.isLongPress = isLongPress;  
  20.     }  
  21.   
  22.     @Override  
  23.     public void run() {  
  24.         if(isLongPress){  
  25.             longClickOnScreen(x,y);  
  26.         }else{  
  27.             onClick();  
  28.         }  
  29.     }  
  30.   
  31.   
  32.     private void longClickOnScreen(int x, int y) {  
  33.         final Instrumentation inst = new Instrumentation();  
  34.         try {  
  35.             long downTime = SystemClock.uptimeMillis();  
  36.             long eventTime = SystemClock.uptimeMillis();  
  37.             final MotionEvent eventDown = MotionEvent.obtain(downTime,  
  38.                     eventTime, MotionEvent.ACTION_DOWN, x, y, 0);  
  39.             eventDown.setSource(InputDevice.SOURCE_TOUCHSCREEN);  
  40.             final MotionEvent eventMove = MotionEvent.obtain(downTime, eventTime,  
  41.                     MotionEvent.ACTION_MOVE, x, y+10);  
  42.             eventMove.setSource(InputDevice.SOURCE_TOUCHSCREEN);  
  43.             final MotionEvent eventUp = MotionEvent.obtain(downTime, eventTime,  
  44.                     MotionEvent.ACTION_UP, x, y, 0);  
  45.             eventUp.setSource(InputDevice.SOURCE_TOUCHSCREEN);  
  46.             inst.sendPointerSync(eventDown);  
  47.             inst.sendPointerSync(eventMove);  
  48.             try {  
  49.                 Thread.sleep(650);  
  50.             } catch (InterruptedException e) {  
  51.                 e.printStackTrace();  
  52.             }  
  53.             inst.sendPointerSync(eventUp);  
  54.         } catch (NullPointerException e) {  
  55.             e.printStackTrace();  
  56.         }  
  57.     }  
  58.   
  59.   
  60.   
  61.     private void onClick(){  
  62.   
  63.         Instrumentation inst = new Instrumentation();  
  64.         inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),  
  65.                 MotionEvent.ACTION_DOWN, x, y, 0));  
  66.         inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),  
  67.                 MotionEvent.ACTION_UP, x, y, 0));  
  68.         //Log.v("LOG", " x = " + x + " y = " + y);  
  69.   
  70.     }  
  71. }  

接下来是长按WebView先要显示的菜单代码


  1. public void showMenu(View v){  
  2.        Activity mContext = this;  
  3.        android.app.FragmentTransaction mFragTransaction = mContext.getFragmentManager().beginTransaction();  
  4.        android.app.Fragment fragment =  mContext.getFragmentManager().findFragmentByTag("dialogFragment");  
  5.        if(fragment!=null){  
  6.            mFragTransaction.remove(fragment);  
  7.        }  
  8.   
  9.        ListDialogFragment dialogFragment = ListDialogFragment.newInstance("bookmarkFragment");  
  10.        dialogFragment.setWidthPercent(0.38f,0.38f);  
  11.   
  12.   
  13.        focusedRawPosition = ((WebViewCopyText) v).getTouchLocation();  
  14.        dialogFragment.optimzeLocation(v,focusedRawPosition);  
  15.   
  16.        dialogFragment.setGravityAndXY(Gravity.LEFT|Gravity.TOP, focusedRawPosition[0],focusedRawPosition[1]);  
  17.        String[] menuStrs = new String[]{"自由复制","复制连接","分享网页"};  
  18.        dialogFragment.setListData(menuStrs);  
  19.        dialogFragment.setIsEnaledGravityAndXY(true);  
  20.        dialogFragment.setOnListDialogItemClickListener(new ListDialogFragment.OnListDialogItemClickListener() {  
  21.            @Override  
  22.            public void onClick(int position) {  
  23.                webView.getHandler().postDelayed(new Runnable() {  
  24.                    @Override  
  25.                    public void run() {  
  26.   
  27.                        //先清空长按监听避免再次显示菜单,再听定时回调设置回来  
  28.                        webView.setOnLongClickListener(null);  
  29.   
  30.                        //执行点击事件  
  31.                        new Thread(new TouchEventRunnable(focusedRawPosition[0],focusedRawPosition[1]+getStateBarHeight(),true)).start();  
  32.   
  33.                        webView.getHandler().postDelayed(new Runnable() {  
  34.                            @Override  
  35.                            public void run() {  
  36.                                webView.setOnLongClickListener(onLongClickListener);  
  37.   
  38.                            }  
  39.                        },2500);  
  40.   
  41.                    }  
  42.                },100);  
  43.   
  44.            }  
  45.        });  
  46.   
  47.   
  48.        dialogFragment.show(mFragTransaction, "dialogFragment");//显示  
  49.   
  50.   
  51.    }  

上面的代码主要是实现模拟长按操作进入自由复制文字选择模式。

但问题又来了,实际操作发现不管是模拟触发的还是WebView默认的,在同一个网页中有时可以进入文字选择默认,有时则不能,甚至有的网页怎么也无法进入。

通过浏览器调试,发现能进入复制文字选择魔的往往是HTML的h1~h6,span,p之类的元素,凡是长按a元素没有一个网页能进入自由复制模式的,再次对a原始的各个属性进行排查问题出在a元素的href属性上。

排查的结果是:

当HTML上的a元素设置了href属性时无法无法进入自由复制模式,但当a元素没有设置设置href属性时,则可以进入。

这下好了,用js的方法element.removeAttribute('href');把HTML上的所有的a元素的href属性移除掉,又可以进文字选择模式了。

至于为什么会是这样水平有限,无法深入研究。
下面是js移除href属性的代码.

[javascript] view plain copy print?
  1. /** 
  2. 开始选择文字是去除a标签的href属性 
  3. **/  
  4. function startSelectText(){  
  5.     var ass = document.getElementsByTagName('a');  
  6.   
  7.     for(var i = 0; i < arr.length; i++){  
  8.         var tag = arr[i];  
  9.         if(tag != null && tag.tagName != null){  
  10.             tag = tag.tagName.toLocaleLowerCase();  
  11.              if(tag != null &&  tag == 'a'){  
  12.   
  13.                  var ele = arr[i];  
  14.                  var hed = ele.href;  
  15.                  if(hed){  
  16.                      var aHref = hed.value;  
  17.                      ele.removeAttribute('href');  
  18.                      ele.setAttribute('copyhref',aHref);  
  19.                  }  
  20.              }  
  21.          }  
  22.     }  
  23.   
  24. }  

实现的效果如下

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(0)

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

广告投放| 申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

返回顶部