Android 从 textView 自定义选择操作模式中删除 CAB 菜单
Android Remove CAB menu from textView Custom Selection Action Mode
我通过这段代码添加了自定义上下文菜单。
ns_text_menu.xml 只包含两项。
this.textViewTest.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
mode.setTitle("Menu");
mode.getMenuInflater().inflate(R.menu.ns_text_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getTitle().equals("View Vocab")) {
ErrorController.showToast(mContext, "View Vocab : " + textViewTest.getText().toString().substring(textViewTest.getSelectionStart(), textViewTest.getSelectionEnd()));
}else{//cpy
ErrorController.showToast(mContext, "Copy : " + textViewTest.getSelectionStart() + ", " + textViewTest.getSelectionEnd());
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
正如这个答案中提到的(),我使用了代码
menu.clear();
在 onCreateActionMode 上清除默认 CAB 菜单。它清除了一些默认的上下文菜单,但是,这两个菜单仍然存在:
'select all' 和 'dictionary'。
测试机器是galaxy s9+(android 8.0),一个nexus emulator(6.0)。
它们都显示出意想不到的菜单。
我该如何解决这个问题?
好像是在onPrepareActionMode上添加了意想不到的菜单。
要解决此问题,
(1) 将我的自定义菜单的 ID 存储在全局列表中。
(2) 在 onPrepareActionMode 中,移除所有与上面列表中存储的 id 不匹配的菜单。
代码如下所示。
this.textViewTest.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
private List<Integer> validResIdList = new ArrayList<>();
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
validResIdList.clear();
mode.getMenuInflater().inflate(R.menu.ns_text_menu, menu);
for (int i = 0; i < menu.size(); i++) {
validResIdList.add(menu.getItem(i).getItemId());
}
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
List<Integer> toRemoveResId = new ArrayList<>();
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).getItemId() != (validResIdList.get(0)) && menu.getItem(i).getItemId() != (validResIdList.get(1))) {
toRemoveResId.add(menu.getItem(i).getItemId());
}
}
for (Integer resId : toRemoveResId) {
menu.removeItem(resId);
}
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if(validResIdList != null && validResIdList.size() > 0){
if (item.getItemId() == validResIdList.get(0)) {
ErrorController.showToast(mContext, "View Vocab : " + textViewTest.getText().toString().substring(textViewTest.getSelectionStart(), textViewTest.getSelectionEnd()));
mode.finish();
} else {//cpy
ErrorController.showToast(mContext, "Copy : " + textViewTest.getSelectionStart() + ", " + textViewTest.getSelectionEnd());
mode.finish();
}
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
我之所以在 R.id.xxx 上使用 validResIdList 是因为我在一个图书馆项目上实施它。
如果您在应用程序项目中,您可以使用 R.id.xxx 来确定您正在处理的菜单。
我通过这段代码添加了自定义上下文菜单。
ns_text_menu.xml 只包含两项。
this.textViewTest.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
mode.setTitle("Menu");
mode.getMenuInflater().inflate(R.menu.ns_text_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getTitle().equals("View Vocab")) {
ErrorController.showToast(mContext, "View Vocab : " + textViewTest.getText().toString().substring(textViewTest.getSelectionStart(), textViewTest.getSelectionEnd()));
}else{//cpy
ErrorController.showToast(mContext, "Copy : " + textViewTest.getSelectionStart() + ", " + textViewTest.getSelectionEnd());
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
正如这个答案中提到的(
menu.clear();
在 onCreateActionMode 上清除默认 CAB 菜单。它清除了一些默认的上下文菜单,但是,这两个菜单仍然存在:
'select all' 和 'dictionary'。
测试机器是galaxy s9+(android 8.0),一个nexus emulator(6.0)。
它们都显示出意想不到的菜单。
我该如何解决这个问题?
好像是在onPrepareActionMode上添加了意想不到的菜单。
要解决此问题,
(1) 将我的自定义菜单的 ID 存储在全局列表中。 (2) 在 onPrepareActionMode 中,移除所有与上面列表中存储的 id 不匹配的菜单。
代码如下所示。
this.textViewTest.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
private List<Integer> validResIdList = new ArrayList<>();
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
validResIdList.clear();
mode.getMenuInflater().inflate(R.menu.ns_text_menu, menu);
for (int i = 0; i < menu.size(); i++) {
validResIdList.add(menu.getItem(i).getItemId());
}
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
List<Integer> toRemoveResId = new ArrayList<>();
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).getItemId() != (validResIdList.get(0)) && menu.getItem(i).getItemId() != (validResIdList.get(1))) {
toRemoveResId.add(menu.getItem(i).getItemId());
}
}
for (Integer resId : toRemoveResId) {
menu.removeItem(resId);
}
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if(validResIdList != null && validResIdList.size() > 0){
if (item.getItemId() == validResIdList.get(0)) {
ErrorController.showToast(mContext, "View Vocab : " + textViewTest.getText().toString().substring(textViewTest.getSelectionStart(), textViewTest.getSelectionEnd()));
mode.finish();
} else {//cpy
ErrorController.showToast(mContext, "Copy : " + textViewTest.getSelectionStart() + ", " + textViewTest.getSelectionEnd());
mode.finish();
}
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
我之所以在 R.id.xxx 上使用 validResIdList 是因为我在一个图书馆项目上实施它。
如果您在应用程序项目中,您可以使用 R.id.xxx 来确定您正在处理的菜单。