I have implemented an ActionMode.Callback
for custom text selection functions within a WebView
. The problem that I am having is that the selection and the action mode states do not match.
When I long-press, everything starts out just fine.
When I interact with one of the buttons, or the WebView
(excluding the actual selection) then the ActionMode
should be destroyed, and the selection should disappear.
In Android 4.4, KitKat, this is exactly what happens.
However, this is not what is happening in 4.1.1 - 4.3, Jelly Bean. When I click one of the buttons, the selection is not removed.
When I tap outside the selection, just the opposite happens. The selection is removed, but the contextual action bar remains on the screen.
Here is the code for my
CustomWebView
public class CustomWebView extends WebView {
private ActionMode.Callback mActionModeCallback;
@Override
public ActionMode startActionMode(Callback callback) {
ViewParent parent = getParent();
if (parent == null) {
return null;
}
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.contextual_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.
loadJavascript("javascript:getSelectedTextInfo()");
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.button_1:
// do stuff
break;
...
default:
break;
}
mode.finish(); // Action picked, so close the CAB
return true;
}
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
// TODO This does not work in Jelly Bean (API 16 - 18; 4.1.1 - 4.3).
clearFocus(); // Remove the selection highlight and handles.
}
}
}
As the comment above shows, I believe the problem is with the clearFocus()
method. When I remove that method, pressing a button leaves the selection behind in 4.4, just like the behavior in Jelly Bean. clearFocus()
gives the expected behavior in 4.4, but is not transferring to earlier APIs. (Do note that clearFocus()
is not new to KitKat; it has been in Android since API 1.)
How can this be fixed?