我使用了Google和本教程中的指南来制作我自己的上下文操作栏.
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { // Called when the action mode is created; startActionMode() was called @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.annotation_menu, menu); return true; } // Called each time the action mode is shown. // Always called after onCreateActionMode, but // may be called multiple times if the mode is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // Return false if nothing is done } // Called when the user selects a contextual menu item @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.custom_button: // do some stuff break; case R.id.custom_button2: // do some other stuff break; default: // This essentially acts as a catch statement // If none of the other cases are true, return false // because the action was not handled return false; } finish(); // An action was handled, so close the CAB return true; } // Called when the user exits the action mode @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; } };
此菜单旨在在用户选择文本时显示,因此它将覆盖本机复制/粘贴菜单.现在我谈到我的问题.
因为我正在覆盖文本选择的功能,所以我还添加了LongClickListener
一个WebView
并实现了该onLongClick(View v)
方法,以便我可以检测用户何时进行选择.
myWebView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (mActionMode != null) { return false; } mActionMode = startActionMode(mActionModeCallback); v.setSelected(true); return true; } });
当我长按,我看到我的自定义菜单出现,但没有突出显示文本.
我需要有文本选择功能; 没有它,我的菜单毫无意义.
如何覆盖onLongClick(View v)
,但保持Android提供的文本选择?
如果无法做到这一点,我是否可以拨打startActionMode(mActionModeCallback)
其他地方的电话,以便正常选择文字,但我的自定义菜单也会出现?
如果这些都不可能......帮助.
有一个更容易的方式!请参阅以下更新:D
我根据这个答案遵循了这个建议,稍加调整以更接近地匹配被覆盖的代码:
public class MyWebView extends 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一起消失:
public class MyWebView extends WebView { ... private class CustomActionModeCallback implements ActionMode.Callback { ... // Everything up to this point is the same as in the question // 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; } } }
这里的所有都是它的.请注意,只要您使用MyWebView
被覆盖的内容startActionMode
,就无法获得本机CAB(复制/粘贴菜单,如果是WebView).有可能实现这种行为,但这不是这段代码的工作方式.
该解决方案提供的控制较少ActionMode
,但它需要的代码远少于上述解决方案.
public class MyActivity extends Activity { 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); } }
这是一个示例菜单,可以帮助您入门:
<!-- my_custom_menu.xml --> <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <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> </menu>
而已!你完成了!现在您的自定义菜单将显示,您不必担心选择,您几乎不必关心ActionMode
生命周期.
这几乎完美无缺地WebView
占据了整个父母Activity
.如果View
你Activity
的同时有多个s,我不确定它会有多好用.在这种情况下,可能需要进行一些调整.