EditText 的 onCreateContextMenu() 在真实设备上不起作用
-
25-09-2019 - |
题
刚刚尝试在真实设备(带有 Android 2.2 的 HTC Desire Z)上测试我的应用程序。发现我的上下文菜单根本不起作用 EditText
s。否则上下文菜单可以工作:在 ListView
, ImageView
等等。在模拟器上一切正常...
当我点击 EditText 时,它会显示类似缩放框的内容,然后显示不寻常的(与标准 Android 类似)上下文菜单,其中显示:“选择文本”、“选择全部”。它不显示我的菜单。以下是截图:
但没有像模拟器中那样的菜单 - 看这里
这是我的活动的源代码:
public class MyActivity extends Activity
{
private static final String TAG=MyActivity.class.getName();
EditText editText;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText=(EditText )findViewById(R.id.editText);
this.registerForContextMenu(editText);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo)
{
Log.v(TAG, "Creating context menu for view="+view);
menu.add(Menu.NONE, Menu.FIRST+1, Menu.NONE, "Test menu");
super.onCreateContextMenu(menu, view, menuInfo);
}
@Override
public boolean onContextItemSelected(MenuItem item)
{
Log.v(TAG, "Context item selected as="+item.toString());
return super.onContextItemSelected(item);
}
}
我已经彻底调试/记录了我的代码周围的所有内容,但仍然没有调用 Activity.onCreateContextMenu() (尽管它以正确的方式注册)。
请帮忙 - 这可能是什么?这与 HTC 的特性有关吗?
解决方案
是的,我想您看到的是 HTC 菜单。
我相信,您所看到的图形编辑上下文菜单是最新 Desire 型号(Desire HD 和 Desire Z)的新功能。我在原始 Desire 上看到的(使用您的代码)是一个基于文本的弹出菜单,其中 HeaderTitle 设置为“编辑文本”和一个列表,例如“全选”、“复制”、“粘贴”等。但是,我也看到一个条目说“测试菜单”。
我发现,当为 ListView 和 ImageView 等调用 onCreateContextMenu() 时,默认情况下不会预先填充传递给该调用的“菜单”对象。然而,在没有 EditText 的情况下,它被设计为与剪贴板交互,因此系统根据 EditText 的内容状态提供预先填充的菜单(例如,如果选择文本,则提供“复制”选项;如果剪贴板上有文本,则提供“粘贴”选项;...等等)。
我能够通过修改代码清除标题和内容来获得没有“编辑”选项的上下文菜单...
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo)
{
Log.v(TAG, "Creating context menu for view="+view);
// Clear current contents
menu.clearHeader();
menu.clear();
menu.setHeaderTitle("TEST MENU");
menu.add(Menu.NONE, Menu.FIRST+1, Menu.NONE, "Test menu");
super.onCreateContextMenu(menu, view, menuInfo);
}
事实上,您获得的图形菜单(可能源自 ContextMenu)表明上述技术不起作用,因此解决该问题的唯一方法是实例化您自己的 ContextMenu 对象,而不是使用传递给 onCreateContextMenu() 的对象。
我已经彻底调试/记录了我的代码周围的所有内容,但仍然没有调用 Activity.onCreateContextMenu()
这看起来很奇怪 - 显然它是为我调用的,因为我已经能够使用传递给它的 ContextMenu 了。
编辑1: 重新思考这一点,您提到您“点击”了 EditText - 这就是您实际上正在做的事情(短距离触摸然后手指向上)?
要获取上下文菜单,我必须“长按”/单击(触摸并按住约 1 秒)。当我只需点击/触摸我的 EditText 时,就会出现“软”键盘,或者,如果键盘已经可见,则光标只需移动到 EditText 框中的其他位置即可。
显然,Desire Z 有一个物理键盘,这可能会导致行为略有不同(以及 Desire Z 的 Sense UI 版本与我的 Desire 不同)。
事实上,onCreateContextMenu() 永远不会被调用,这一事实只能意味着一件事,那就是,您看到的不是 ContextMenu,而是某种其他类型的弹出 UI 元素。至少这是我能理解的唯一合乎逻辑的方式。
您能否确认“长按”仍然不会为您创建上下文菜单,或者您一直在使用长按?
如果您尝试过长按,请尝试按如下方式修改代码......
实现 OnClickListener
public class MyActivity extends Activity implements OnLongClickListener {
在 onCreate 中设置 editText 的监听器...
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); editText=(EditText )findViewById(R.id.editText); this.registerForContextMenu(editText); editText.setOnLongClickListener(this); // <-- ADD THIS }
添加监听器代码...
@Override public boolean onLongClick(View arg0) { android.util.Log.v(TAG, "onLongClick() called"); if (arg0 == editText) { android.util.Log.v(TAG, "arg0 == editText"); Toast.makeText(this, "onLongClick intercepted", 2000).show(); return true; } else { android.util.Log.v(TAG, "arg0 != editText"); return false; } }
通过这样做,我能够拦截长按,并且通过从 onLongClick() 返回“true”,我向系统表明我已经“消耗”了该事件,并且它不会被传递以导致创建我的上下文菜单。
如果这对您不起作用并且短按仍然会导致弹出窗口出现,请尝试实现 OnClickListener 并重写 onClick() 。
本练习的目的是,如果您可以拦截导致创建您所看到的弹出窗口的任何内容,则您可以手动创建并显示您自己的上下文菜单。
其他提示