我正在自定义WebView
中创建自定义上下文操作栏(CAB)。
我的要求是从第一个CAB中选择一个特定选项将打开第二个CAB。这是最终目标:
我已经做到了这一点,但选择不正常。我知道它看起来是正确的,但如果用户点击其他三个图标中的任何一个,结果就是这样:
如果用户在按下四个初始图标中的任何一个后触摸选择,则应用程序因空指针异常而崩溃。
当用户在选择操作后触摸延迟选择时,应用会尝试访问创建带有图标的CAB的ActionMode
(让我们称之为firstActionMode
)以使其无效/刷新。但是,当创建具有颜色的CAB时,firstActionMode
被销毁(调用secondActionMode
)导致空指针异常。
为了清除选择,我发现在clearFocus()
方法中调用onDestroyActionMode(firstActionMode)
可以很好地完成工作。
private class CustomActionModeCallback extends ActionMode.Callback {
@Override
public void onDestroyActionMode(ActionMode mode) {
clearFocus();
}
}
但是,实施此操作后,secondActionMode
创建其CAB时选择不会保留:
从这一点选择颜色实际上会产生所需的功能。然而,虽然这“有效”,但(最不幸的是)它不符合我的要求。当显示由secondActionMode
创建的CAB时,我需要选择保持可见和功能。
<小时/> 以下是我的自定义类(
WebView
)及其嵌套ActionMode
s 的代码
public class CustomWebView extends WebView {
private ActionMode.Callback mActionModeCallback;
@Override
public ActionMode startActionMode(Callback callback) {
ViewParent parent = getParent();
if (parent == null) {
return null;
}
if (callback instanceof HighlightActionModeCallback) {
mActionModeCallback = callback;
} else {
mActionModeCallback = new CustomActionModeCallback();
}
return parent.startActionModeForChild(this, mActionModeCallback);
}
private class CustomActionModeCallback implements 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.first_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) {
// This method is called when the handlebars are moved.
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.copy:
// Do stuff
break;
case R.id.bookmark:
// Do stuff
break;
case R.id.highlight:
startActionMode(new HighlightActionModeCallback());
break;
case R.id.note:
// Do stuff
break;
default:
return false;
}
mode.finish(); // Action picked, so close the CAB
return true;
}
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
clearFocus(); // This is commented in the first four screens.
}
}
private class HighlightActionModeCallback implements 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.highlight_colors, 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) {
// This method is called when the handlebars are moved.
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) {
mode.finish(); // Action picked, so close the CAB
return true;
}
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
// Remove the selection highlight and handles.
clearFocus();
}
}
}
<小时/> 怎么解决这个问题?任何和所有的帮助表示赞赏。
答案 0 :(得分:0)
我现在已经解决了这个问题;我过度思考了。解决方案不在于ActionMode
,而在菜单中。
如果选择了荧光笔,则不会为颜色菜单启动全新的ActionMode
,而是更改图标菜单。保存对Menu
中onCreateActionMode
参数的引用,并设置某种标记;我正在使用布尔值。
private class CustomActionModeCallback implements ActionMode.Callback {
private boolean highlighterClicked = false;
private Menu mMenu;
// Called when the action mode is created; startActionMode() was called
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mMenu = menu;
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.first_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) {
// This method is called when the handlebars are moved.
MenuInflater inflater = mode.getMenuInflater();
if (highlighterClicked) {
menu.clear(); // Remove the four icons
inflater.inflate(R.menu.highlight_colors, menu); // Show the colors
return true; // This time we did stuff, so return true
}
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) {
highlighterClicked = false;
switch (item.getItemId()) {
case R.id.copy:
// Do stuff
break;
case R.id.bookmark:
// Do stuff
break;
case R.id.highlight:
highlighterClicked = true;
onPrepareActionMode(mode, mMenu);
return true;
case R.id.note:
// Do stuff
break;
default:
// Any of the colors were picked
return true;
}
mode.finish(); // Action picked, so close the CAB
return true;
}
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
clearFocus();
}
}
选择突出显示和手柄保持活动和功能,颜色选项按预期工作。
删除第二个ActionModeCallback
类是安全的;它毫无价值。再次,过度思考。 :P