EditText的onCreateContextMenu()不适用于真实设备

时间:2010-12-09 20:29:51

标签: android android-edittext contextmenu android-compatibility

试图在真实设备上测试我的应用程序(HTC Desire Z with Android 2.2)。并发现我的上下文菜单在EditText上根本不起作用。否则上下文菜单有效:ListViewImageView等。在模拟器上一切正常......

当我点击EditText时,它显示缩放框架之类的内容,然后显示异常(不是标准的Android)上下文菜单,其中显示:“选择文本”,“全选”。它不显示我的菜单。 以下是截图:

  1. Before tap
  2. During tap
  3. After tap(只是普通的选择文字,全选,粘贴)
  4. 但我的菜单没有像模拟器中那样 - look here

    以下是我的活动的源代码:

    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的特点有关吗?

2 个答案:

答案 0 :(得分:7)

是的,我认为你看到的是一个HTC菜单。

我相信您看到的图形编辑上下文菜单是最新的Desire模型(Desire HD和Desire Z)的新功能。我在原始Desire上看到的(带有你的代码)是一个弹出基于文本的菜单,其中HeaderTitle设置为“编辑文本”,列表如“全选”,“复制”,“粘贴”等。但是,我还要看一个条目“测试菜单”。

我发现当为ListView和ImageView之类的东西调用onCreateContextMenu()时,默认情况下不会预先填充传入该调用的'menu'对象。然而,在关闭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 - 你正在做什么(短暂的触摸然后用手指向上)?

要获得我的ContextMenu,我必须使用'长'按下/点击(触摸并保持约1秒钟)。当我只是点击/触摸我的EditText时,会出现“软”键盘,或者,如果键盘已经可见,则光标只会移动到EditText框中的其他位置。

显然Desire Z有一个物理键盘,可能会导致稍微不同的行为(以及Desire Z为我的欲望提供不同版本的Sense UI)。

永远不会为你调用onCreateContextMenu()的事实只能意味着一件事,那就是你所看到的不是ContextMenu,而是一些其他类型的弹出UI元素。至少这是我理解它的唯一合理方式。

您能否确认“长”按仍然无法为您创建ContextMenu,或者您是否一直使用长按?

如果您尝试了长按,请尝试按如下方式修改代码...

  1. 实施OnClickListener

    public class MyActivity extends Activity
        implements OnLongClickListener {
    
  2. 在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
    }
    
  3. 添加侦听器代码...

    @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;
        }
    }
    
  4. 通过这样做,我能够拦截长按,并通过从onLongClick()返回'true',我向系统指示我'已经'消耗了'事件并且它没有通过on以导致我的ContextMenu的创建。

    如果这对您不起作用,短暂的点击仍然会导致弹出窗口出现,那么请尝试实现OnClickListener并覆盖onClick()。

    练习的目的是,如果您可以拦截导致创建弹出窗口的任何内容,您可以手动创建并显示您自己的ContextMenu。

答案 1 :(得分:-1)

这是您看到的标准剪切/复制/粘贴菜单。

有关详细信息,请参阅此主题:

How can I write my own context menu for copy & paste?

此致 HJW