1.项目背景
在项目开发过程中,由于智能座舱的systemui都是各个主机厂定制的,会存在一些系统弹窗显示异常的情况。如下图所示,我们会发现,在app内部输入一段文字之后,选中,会弹出:复制,粘贴,全选,分享菜单,选中分享之后,会出现弹框显示不全的情况。
当然,正确的解决方法应该是调整系统弹框的位置,使得弹框能够正常显示。但是由于智能座舱没有需要分享的app或者功能,所以对于智能座舱,我们需要去掉分享的功能。那么分享这个菜单是如何显示出来的,应该怎么修改呢?
2.代码流程梳理
基本分析:这个菜单是在EditText里面弹出来的,那么肯定与EditText控件有关,而EditText又继承至TextView,并且Editor 是TextView最核心的组件,所以分享菜单的显示流程,肯定与这三个类密不可分。
Helper class used by TextView to handle editable text views.
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mAssistClickHandlers.clear();
mode.setTitle(null);
mode.setSubtitle(null);
mode.setTitleOptionalHint(true);
populateMenuWithItems(menu);
Log.w(TAG, "android200, onCreateActionMode enter");
Callback customCallback = getCustomCallback();
if (customCallback != null) {
if (!customCallback.onCreateActionMode(mode, menu)) {
// The custom mode can choose to cancel the action mode, dismiss selection.
Selection.setSelection((Spannable) mTextView.getText(),
mTextView.getSelectionEnd());
return false;
}
}
if (mTextView.canProcessText()) {
mProcessTextIntentActionsHandler.onInitializeMenu(menu);
}
if (mHasSelection && !mTextView.hasTransientState()) {
mTextView.setHasTransientState(true);
}
return true;
}
private void populateMenuWithItems(Menu menu) {
if (mTextView.canCut()) {
menu.add(Menu.NONE, TextView.ID_CUT, MENU_ITEM_ORDER_CUT,
com.android.internal.R.string.cut)
.setAlphabeticShortcut('x')
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
...
if (mTextView.canShare()) {
menu.add(Menu.NONE, TextView.ID_SHARE, MENU_ITEM_ORDER_SHARE,
com.android.internal.R.string.share)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
Log.w(TAG, "android200, add menu 222");
}
public boolean onTextContextMenuItem(int id) {
Log.d(LOG_TAG, "android200, onTextContextMenuItem = " + id);
int min = 0;
int max = mText.length();
if (isFocused()) {
final int selStart = getSelectionStart();
final int selEnd = getSelectionEnd();
min = Math.max(0, Math.min(selStart, selEnd));
max = Math.max(0, Math.max(selStart, selEnd));
Log.d(LOG_TAG, "android200, onTextContextMenuItem selStart = " + selStart + ", selEnd = " + selEnd+ ", min = " + min+ ", max = " + max);
}
switch (id) {
...
case ID_SHARE:
shareSelectedText();
return true;
}
return false;
}
private void shareSelectedText() {
String selectedText = getSelectedText();
Log.d(LOG_TAG, "android200, shareSelectedText = " + selectedText);
if (selectedText != null && !selectedText.isEmpty()) {
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.removeExtra(android.content.Intent.EXTRA_TEXT);
selectedText = TextUtils.trimToParcelableSize(selectedText);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, selectedText);
getContext().startActivity(Intent.createChooser(sharingIntent, null));
Selection.setSelection(mSpannable, getSelectionEnd());
Log.d(LOG_TAG, "android200, shareSelectedText = " + Intent.createChooser(sharingIntent, null));
}
}
在上面的代码处添加log,然后抓取log如下:
09-03 19:09:29.631 7284 7284 W Editor : android200, add menu 222
09-03 19:09:29.632 7284 7284 W Editor : android200, onCreateActionMode enter
09-03 19:09:32.640 7284 7284 D TextView: android200, onTextContextMenuItem = 16908341
09-03 19:09:32.640 7284 7284 D TextView: android200, onTextContextMenuItem selStart = 0, selEnd = 3, min = 0, max = 3
09-03 19:09:32.640 7284 7284 D TextView: android200, shareSelectedText = 我我我
09-03 19:09:32.662 7284 7284 D TextView: android200, shareSelectedText = Intent { act=android.intent.action.CHOOSER flg=0x1 clip={text/plain {T(3)}} (has extras) }
3.最终修改方案:
需要将两处add share menu的地方注掉。如下所示: