上下文菜单

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找到了performContextClick
public 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,详细代码太多了,就不贴出来了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值