如何覆盖android中的web视图文本select菜单

基本的android的web文本select菜单如下图所示。 它有复制,共享,全选,网页search等选项。

在这里输入图像说明

我想骑这个菜单,并希望他们作为我自己的菜单列表,如“标记颜色”,“标记为IMP”等我环顾大多数关于堆栈溢出上下文菜单的问题。 大部分的问题都与上下文菜单有关,但并不像预期的那样给出结果。 我想要像下面的图像菜单

在这里输入图像说明

当我执行selectAndroid监视器显示一些视图创buildformsviewRoot像

D/ViewRootImpl: #1 mView = android.widget.PopupWindow$PopupDecorView{648898f VE..... ......I. 0,0-0,0} D/ViewRootImpl: #1 mView = android.widget.PopupWindow$PopupDecorView{a66541c VE..... ......I. 0,0-0,0} D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1 D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1 

如何实现这样的实现?

我也通过https://github.com/naoak/WebViewMarker但没有得到正确的结果。

我做了什么呢?

我扩展了android的WebView,我想支持最低的SDK 19.当我长时间按下我得到了长按事件,但我不能得到这样的菜单创buildAPI调用。

Solutions Collecting From Web of "如何覆盖android中的web视图文本select菜单"

您需要覆盖活动的操作菜单

更多的信息,你可以阅读: https : //developer.android.com/guide/topics/ui/menus.html

如何覆盖:

 @Override public void onActionModeStarted(android.view.ActionMode mode) { mode.getMenu().clear(); Menu menus = mode.getMenu(); mode.getMenuInflater().inflate(R.menu.highlight,menus); super.onActionModeStarted(mode); } 

突出

  <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/impclick" android:title="Mark As Important" /> <item android:id="@+id/colorclick" android:title="Mark with color" /> </menu> 

我想在这里可以帮助你。

为了完整性,这里是我如何解决这个问题:

我根据这个答案跟随了这个build议,稍微调整一下,以便更接近地匹配重写的代码:

公共类MyWebView扩展WebView {

 private ActionMode mActionMode; private mActionMode.Callback mActionModeCallback; @Override public ActionMode startActionMode(Callback callback) { ViewParent parent = getParent(); if (parent == null) { return null; } mActionModeCallback = new CustomActionModeCallback(); return parent.startActionModeForChild(this, mActionModeCallback); } 

}

实质上,这会强制您的自定义CAB出现而不是Android CAB。 现在,您必须修改您的回叫,以便文本突出显示将与CAB一起消失:

公共类MyWebView扩展WebView {…私人类CustomActionModeCallback实现ActionMode.Callback {… / /一切到这一点是一样的在问题

  // Called when the user exits the action mode @Override public void onDestroyActionMode(ActionMode mode) { clearFocus(); // This is the new code to remove the text highlight mActionMode = null; } } 

}

这里的所有都是它的。 请注意,只要您使用带重写的startActionMode的MyWebView,就没有办法获取本地CAB(在WebView的情况下为复制/粘贴菜单)。 实现这种行为可能是可能的,但这不是这种代码的工作方式。 更新:有一个更简单的方法来做到这一点! 上述解决scheme运作良好,但这是一个替代scheme,更简单的方法。

此解决scheme对ActionMode的控制较less,但与上述解决scheme相比,所需代码less得多。

公共类MyActivity扩展活动{

 private ActionMode mActionMode = null; @Override public void onActionModeStarted(ActionMode mode) { if (mActionMode == null) { mActionMode = mode; Menu menu = mode.getMenu(); // Remove the default menu items (select all, copy, paste, search) menu.clear(); // If you want to keep any of the defaults, // remove the items you don't want individually: // menu.removeItem(android.R.id.[id_of_item_to_remove]) // Inflate your own menu items mode.getMenuInflater().inflate(R.menu.my_custom_menu, menu); } super.onActionModeStarted(mode); } // This method is what you should set as your item's onClick // <item android:onClick="onContextualMenuItemClicked" /> public void onContextualMenuItemClicked(MenuItem item) { switch (item.getItemId()) { case R.id.example_item_1: // do some stuff break; case R.id.example_item_2: // do some different stuff break; default: // ... break; } // This will likely always be true, but check it anyway, just in case if (mActionMode != null) { mActionMode.finish(); } } @Override public void onActionModeFinished(ActionMode mode) { mActionMode = null; super.onActionModeFinished(mode); } 

}

这里是一个菜单,让你开始:

 <item android:id="@+id/example_item_1" android:icon="@drawable/ic_menu_example_1" android:showAsAction="always" android:onClick="onContextualMenuItemClicked" android:title="@string/example_1"> </item> <item android:id="@+id/example_item_2" android:icon="@drawable/ic_menu_example_2" android:showAsAction="ifRoom" android:onClick="onContextualMenuItemClicked" android:title="@string/example_2"> </item> 

而已! 你完成了! 现在你的自定义菜单会显示出来,你不必担心select,你几乎不必担心ActionMode的生命周期。

这对于占用其整个父Activity的WebView几乎是完美无缺的。 如果同时在您的活动中有多个视图,我不确定它会如何工作。 在这种情况下,这可能需要一些调整。

这个解决scheme不是依赖于Activity的Action模式,而是适用于所有的Android平台

我试图给出答案,但它超过了字符限制,所以我把一些代码部分

参考链接1用于在Web视图上进行select

https://github.com/btate/BTAndroidWebViewSelection

参考链接2用于制作Web视图标记

https://github.com/liufsd/WebViewMarker

上面的链接确实扮演着重要的angular色,由一些优秀的开发者开发。 首先需要对TextSelectionSupport类从参考链接进行一些研究1.我在TextSelectionSupport类中定制了两行代码,在这里select了Listener中的矩形。

从这里克隆示例项目https://github.com/ab-cse-2014/WebViewSelection.git

请参阅CustomWebView的实现和使用TextSelectionSupport类。

这是我在项目中的Web视图类

  import android.content.Context; import android.graphics.Rect; import android.os.Build; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.webkit.WebView; import android.widget.PopupWindow; import android.widget.Toast; import com.cse.webviewtextselection.R; import com.cse.webviewtextselection.webviewmaker.TextSelectionSupport; public class CustomWebView extends WebView { private final String TAG = this.getClass().getSimpleName(); private Context mContext; private TextSelectionSupport mTextSelectionSupport; private PopupWindow mPopupWindow; private int currentTop; public CustomWebView(Context context) { super(context); mContext = context; initSetUp(); preparePopupWindow(); } public CustomWebView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; initSetUp(); preparePopupWindow(); } public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; initSetUp(); preparePopupWindow(); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mContext = context; initSetUp(); preparePopupWindow(); } private void initSetUp() { mTextSelectionSupport = TextSelectionSupport.support((AppCompatActivity) mContext, this); mTextSelectionSupport.setSelectionListener(new TextSelectionSupport.SelectionListener() { @Override public void startSelection() { } @Override public void selectionChanged(String text, Rect rect) { Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show(); showPopAtLocation(mPopupWindow, rect.left, rect.top); } @Override public void endSelection() { if (mPopupWindow != null) { mPopupWindow.dismiss(); } } }); } private void preparePopupWindow() { LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View customPopupView = layoutInflater.inflate(R.layout.custom_popup_layout, null); mPopupWindow = new PopupWindow(customPopupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true); mPopupWindow.setAnimationStyle(android.R.style.Animation_Dialog); } private void showPopAtLocation(PopupWindow mPopupWindow, int x, int y) { if (mPopupWindow != null) { if (currentTop != 0 || currentTop > ((AppCompatActivity)mContext).getWindow().getDecorView().getHeight()) { if (y > currentTop) { y -= currentTop; } } Log.d("Current Top : ", String.valueOf(currentTop)); Log.d("Y : ", String.valueOf(y)); //mPopupWindow.showAtLocation(((AppCompatActivity)mContext).findViewById(R.id.parentRelativeLayout), Gravity.NO_GRAVITY, x, y); mPopupWindow.showAtLocation(((AppCompatActivity)mContext).getWindow().getDecorView(), Gravity.NO_GRAVITY, x, y); } } @Override protected void onScrollChanged(int newLeft, int newTop, int oldLeft, int oldTop) { currentTop = newTop; super.onScrollChanged(newLeft, newTop, oldLeft, oldTop); } } 

自定义popup式菜单XML像androids智能文本select(custom_popup_layout.xml)

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/myCustomMenuLinearLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@android:color/transparent"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@android:color/white" android:elevation="5dp" android:layout_margin="12dp"> <TextView android:id="@+id/menuOne" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Mark With Color" android:textColor="@android:color/black" android:padding="10dp" android:maxLines="1"/> <TextView android:id="@+id/menuTwo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Mark As Important" android:textColor="@android:color/black" android:padding="10dp" android:maxLines="1"/> <TextView android:id="@+id/menuThree" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show More" android:textColor="@android:color/black" android:padding="10dp" android:maxLines="1"/> </LinearLayout> </LinearLayout> 

输出屏幕截图

选择一

选择二

选择三