gpt4 book ai didi

android - 使用自定义上下文操作栏进行 WebView 文本选择

转载 作者:IT老高 更新时间:2023-10-28 23:10:37 45 4
gpt4 key购买 nike

我用过this guide from Googlethis tutorial生成我自己的上下文操作栏。

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;
}
};

此菜单旨在在用户选择文本时出现,因此它会覆盖 native 复制/粘贴菜单。现在我来解决我的问题。

因为我重写了文本选择的函数,所以我还在 WebView 中添加了一个 LongClickListener 并实现了 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


为了完整起见,这是我解决问题的方法:

我按照 this answer 的建议进行操作, 稍加调整以更紧密地匹配被覆盖的代码:

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 一起使用,就无法获得 native 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 生命周期。

这几乎可以完美地与占据其整个父 ActivityWebView 配合使用。如果您的 Activity 中同时有多个 View,我不确定它的效果如何。在这种情况下可能需要进行一些调整。

关于android - 使用自定义上下文操作栏进行 WebView 文本选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22336903/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com