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

Bar*_*ica 7 android contextmenu android-compatibility android-edittext

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

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

  1. 点击之前
  2. 在点击期间
  3. 点击后(只需普通选择文字,选择全部,粘贴)

但没有像模拟器那样的菜单 - 看这里

这是我活动的源代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经彻底调试/记录了我的代码周围的一切,但仍然没有调用Activity.onCreateContextMenu()(虽然它以适当的方式注册).

请帮忙 - 它可以是什么?它与HTC的特点有关吗?

Squ*_*onk 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);
}
Run Code Online (Sandbox Code Playgroud)

你得到一个图形菜单(可能是从文本菜单衍生)的事实表明,上述技术将不能工作,所以唯一的办法解决这将是实例自己的ContextMenu对象,而不是使用()的一个传递给onCreateContextMenu.

我彻底调试/记录了我的代码周围的一切,但仍然没有调用Activity.onCreateContextMenu()

这看起来很奇怪 - 显然它正在为我调用,因为我已经能够使用传递给它的ContextMenu.

编辑1:重新考虑这一点,你提到你"点击"EditText - 你正在做什么(短暂的触摸然后用手指向上)?

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

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

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

您是否可以确认"长"按仍然无法为您创建ContextMenu,或者您是否一直使用长按?

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

  1. 实现OnClickListener

    public class MyActivity extends Activity
        implements OnLongClickListener {
    
    Run Code Online (Sandbox Code Playgroud)
  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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

通过这样做,我能够拦截长按,并通过从onLongClick()返回'true'我向系统指示我'消耗'了该事件并且它没有被传递到原因创建我的ContextMenu.

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

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