上下文菜单

来源:互联网 发布:苹果手机网络加速软件 编辑:程序博客网 时间:2024/05/22 13:27

Android中实现菜单的方式有:
- Menu
- PopWindow
- ContextMenu
这里来试着说一说ContextMenu的用法。
先来看效果图:
长按textview显示菜单

实现步骤:

  • 为指定的View注册上下文菜单 registerForContextMenu

  • 重写onCreateContextMenu onContextItemSelected这两个方法。

    下面是详细的示例代码:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        TextView textView = (TextView) findViewById(R.id.main_tv);        registerForContextMenu(textView);        Button btn = (Button) findViewById(R.id.main_btn);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(MainActivity.this, "btn is clicked", Toast.LENGTH_SHORT).show();            }        });        registerForContextMenu(btn);    }    @Override    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {        switch (v.getId()) {            case R.id.main_tv:                menu.add(0, 0, 0, "position0");                menu.add(0, 1, 0, "position1");                break;            case R.id.main_btn:                menu.add(0, 2, 0, "position2");                menu.add(0, 3, 0, "position3");                break;            default:                break;        }        super.onCreateContextMenu(menu, v, menuInfo);    }    @Override    public boolean onContextItemSelected(MenuItem item) {        Toast.makeText(this, item.getItemId() + "", Toast.LENGTH_SHORT).show();        return super.onContextItemSelected(item);    }

我们可以看到,可以同时为多个view注册上下文菜单,并且可同时为button设置onClickListener和上下文菜单。到这我产生了一个疑问,我们都知道onClickLisener是在view的onTouchEvent方法里的performClick中被调用的,那上下文菜单是在哪被调用的呢?接下来,只能去看源码。
我们从入口一步一步的找:

public void registerForContextMenu(View view) {//入口        view.setOnCreateContextMenuListener(this);    }   //view的setOnCreateContextMenuListener方法public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {        if (!isLongClickable()) {//If this view is not long clickable, it becomes long clickable            setLongClickable(true);        }        getListenerInfo().mOnCreateContextMenuListener = l;//getListenerInfor()会得到一个ListenerInfo类,它是View的静态内部类,里面持有各种监听器,比如onClickListener、OnFocusChangeListener等    }

可以看到,调用registerForContextMenu只是给view里的变量赋了个值。在哪调用了mOnContextClickListener?接着找吧。

//顺藤摸瓜,顺着mOnContextClickListener找到了performContextClickpublic boolean performContextClick() {        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED);        boolean handled = false;        ListenerInfo li = mListenerInfo;        if (li != null && li.mOnContextClickListener != null) {            handled = li.mOnContextClickListener.onContextClick(View.this);//具体调用的地方        }        if (handled) {            performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);        }        return handled;    }//接着找发现,performAccessibilityActionInternal调用了performContextClick,而performAccessibilityAction调用了performAccessibilityActionInternal方法,所以具体的调用流程是performAccessibilityAction-》performAccessibilityActionInternal-》performContextClick,详细代码太多了,就不贴出来了。
原创粉丝点击