首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

替WebView加上复制文本功能

2012-07-03 
为WebView加上复制文本功能需求描述: ??长按WebView出现Context menu,显示复制”菜单点击上述菜单后选择文

为WebView加上复制文本功能

需求描述: ??

长按WebView出现Context menu,显示"复制”菜单点击上述菜单后选择文本,复制到剪贴板概要设计+详细设计:用OnTouchListener实现长按实现(参照android.view.View)实现WebView的Context menu(在Activity实例中实现)实现复制文本功能(兼容多个sdk)

?

编码:

?

public class WebViewCopy {private Activity activity;private WebView webview;private  static boolean mIsSelectingText;public static final String    TAG=WebViewCopy.class.getSimpleName();        public WebViewCopy(final Activity activity, final WebView webView){   this.webview=webView;   this.activity=activity;   this.activity.registerForContextMenu(this.webview);    webView.requestFocus(View.FOCUS_DOWN);   webView.setOnTouchListener(new OnTouchListener() {      boolean mHasPerformedLongPress;   Runnable mPendingCheckForLongPress;   @Overridepublic boolean onTouch(final View v, MotionEvent event) {/*webView.getSettings().setBuiltInZoomControls(false);webView.getSettings().setSupportZoom(false);*/Log.d(TAG, "event:" + event.getAction());switch (event.getAction()) {            case MotionEvent.ACTION_UP:            mIsSelectingText = false;             if (!v.hasFocus()) {                         v.requestFocus();                        }              if (!mHasPerformedLongPress) {                          // This is a tap, so remove the longpress check                          if (mPendingCheckForLongPress != null) {                              v.removeCallbacks(mPendingCheckForLongPress);                          }                       // v.performClick();              }                                      break;            case  MotionEvent.ACTION_DOWN:                         if (!v.hasFocus()) {                         v.requestFocus();                       }            if( mPendingCheckForLongPress == null) {                                    mPendingCheckForLongPress = new Runnable() {            public void run() {            //((WebView)v).performLongClick();            if(! mIsSelectingText) {            activity.openContextMenu(webview);            mHasPerformedLongPress = true;            mIsSelectingText = false;            }            }            };                        }                                     mHasPerformedLongPress = false;             v. postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout());                        break;                         case MotionEvent.ACTION_MOVE:              final int x = (int) event.getX();                      final int y = (int) event.getY();                      // Be lenient about moving outside of buttons                      int slop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();                      if ((x < 0 - slop) || (x >= v.getWidth() + slop) ||                              (y < 0 - slop) || (y >= v.getHeight() + slop)) {                                            if (mPendingCheckForLongPress != null) {                             v. removeCallbacks(mPendingCheckForLongPress);                          }                                   }             break;              default:              return false;} return false;}});               }    public  static synchronized void  emulateShiftHeld(WebView view) {         try        {            KeyEvent shiftPressEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,                                                    KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0);            shiftPressEvent.dispatch(view);        }        catch (Exception e)        {            Log.e(TAG, "Exception in emulateShiftHeld()", e);        }    } public synchronized void onCreateContextMenu(ContextMenu menu, View v,               ContextMenuInfo menuInfo,final int copy,String menuString) {                MenuItem menuitem=menu.add(1, copy, Menu.NONE, menuString);               menuitem.setOnMenuItemClickListener(new OnMenuItemClickListener() {@Overridepublic boolean onMenuItemClick(MenuItem item) {if(item.getItemId()==copy){//emulateShiftHeld(webview);selectAndCopyText(webview);}return false;}});}  public  static synchronized void selectAndCopyText(WebView v) {     try {          mIsSelectingText = true;                              //Method m = WebView.class.getMethod("emulateShiftHeld", Boolean.TYPE);           //  m.invoke(v, false);          if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR) {     Method m = WebView.class.getMethod("emulateShiftHeld", Boolean.TYPE);            m.invoke(v, false);      }     else  {     Method m = WebView.class.getMethod("emulateShiftHeld");       m.invoke(v);      }                 } catch (Exception e) {            // fallback            emulateShiftHeld(v);        }finally{        //Toast.makeText(activity, "Select text", Toast.LENGTH_SHORT).show();        }}}

?下面的代码在activity中写:

?? ? 1) 在onCreate中生成?WebViewCopy ?实例:?copy = new WebViewCopy(this, _webView);

?? ? 2) 在onCreateContextMenu中注入复制菜单public void onCreateContextMenu(ContextMenu menu, View v,

             ContextMenuInfo menuInfo) {               copy.onCreateContextMenu(menu, v, menuInfo,COPY,getString(R.string.copy));         super.onCreateContextMenu(menu, v, menuInfo);  }

?

?

回顾与总结:

?? ? ? ?OnTouchListener可能在一些时候更本不响应,如Zoom Button出现后。这得让WebView重新获取焦点,

这是WebView又一已知的Bug. ?整个难点在于重新获取焦点: ?webview.requestFocus();

参考:?http://code.google.com/p/android/issues/detail?id=7189

?

?

?

热点排行