##背景
我们经常在列表的页面中,点击列表中的行,一般进入详情页面,长按列表中一行,会弹出一个菜单,包含了对某一行的操作(编辑、删除等等),也知道通常的用法:

  • 0x01. 在Activity中注册需要上下文菜单的View:
    registerForContextMenu(mListView);
  • 0x02. 然后在Activity中继承onCreateContextMenu方法,添加菜单项:

    1
    2
    3
    4
    5
    6
    7
    8
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    Log.d(LOG_TAG, "onCreateContextMenu");
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle(R.string.prompt);
    menu.add(Menu.NONE, R.id.context_menu_item_delete_record, Menu.NONE, R.string.delete_record);//groupId, itemId, order, title
    menu.add(Menu.NONE, R.id.context_menu_item_delete_record_with_file, Menu.NONE, R.string.delete_record_with_file);
    }

    PS:每次长按出现上下文菜单都会调用这个方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /** * Called when a context menu for the {@code view} is about to
    be shown. * Unlike {@link #onCreateOptionsMenu(Menu)}, this will
    be called every * time the context menu is about to be shown and
    should be populated for * the view (or item inside the view for {@link
    AdapterView} subclasses, * this can be found in the {@code
    menuInfo})). * <p> * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an
    * item has been selected. * <p> * It is not safe to hold onto the
    context menu after this method returns. * */
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    }
  • 0x03. 接下来长按列表中一行的时候,会弹出上下文菜单:

  • 0x04. 点击菜单后,在Activity中继承onContextItemSelected方法进行处理:

    1
    2
    3
    4
    5
    @Override
    public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()){
    }
    }
  • 0x05. 获取Item标识(id)
    我们删除数据库或者一行记录的时候,要知道主键(一般是id)才能进行操作,很多人就想办法,有的是把ListView的每个ItemView添加一个LongClickListener,然后长按的时候记录下Position,然后在进行相应处理。

    其实有更优雅的做法,onContextItemSelected(MenuItem item)回调的参数item可以获取item.getMenuInfo(),在ListView和Adapter的模式中,可以强制转换成AdapterContextMenuInfo,拿到targetView(即所长按行的ItemVew,如果我们需要什么参数,直接放到View.setTag中去即可):

    1
    2
    3
    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    int index = info.position;
    View view = info.targetView;

至此,常见的用法就完了,那么遇到其他自定义View呢?

  • 0x06. 自定义View的ContextMenu实现
    下面以用到的RecycleView为例,没有了ListView及其Adapter的封装,我们需要自己处理ContextMenu。
    最重要的是继承View的两个方法:
    1.上下文菜单Item的附加信息(上面item.getMenuInfo());
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /** * Views should implement this if they have extra information to
    associate * with the context menu. The return result is supplied as a
    parameter to * the {@link
    OnCreateContextMenuListener#onCreateContextMenu(ContextMenu,
    View, ContextMenuInfo)} * callback. * * @return Extra information
    about the item for which the context menu * should be shown.
    This information will vary across different * subclasses of View. */
    protected ContextMenuInfo getContextMenuInfo() {
    return null;
    }

2.ViewGroup的showContextMenuForChild,每次弹出上下文菜单都会调用此方法,需要在这里更新ContextMenuInfo;

1
2
3
4
/** * {@inheritDoc} */
public boolean showContextMenuForChild(View originalView) {
return mParent != null && mParent.showContextMenuForChild(originalView);
}
  • 0x07. 自定义RecycleView的ContextMenu全部代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

大专栏  ConxtMenu高级用法v class="line">163

ConxtMenu高级用法的更多相关文章

  1. Visual Studio 宏的高级用法

    因为自 Visual Studio 2012 开始,微软已经取消了对宏的支持,所以本篇文章所述内容只适用于 Visual Studio 2010 或更早期版本的 VS. 在上一篇中,我已经介绍了如何编 ...

  2. SolrNet高级用法(分页、Facet查询、任意分组)

    前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...

  3. sqlalchemy(二)高级用法

    sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...

  4. Solr学习总结(六)SolrNet的高级用法(复杂查询,分页,高亮,Facet查询)

    上一篇,讲到了SolrNet的基本用法及CURD,这个算是SolrNet 的入门知识介绍吧,昨天写完之后,有朋友评论说,这些感觉都被写烂了.没错,这些基本的用法,在网上百度,资料肯定一大堆,有一些写的 ...

  5. 再谈Newtonsoft.Json高级用法

    上一篇Newtonsoft.Json高级用法发布以后收到挺多回复的,本篇将分享几点挺有用的知识点和最近项目中用到的一个新点进行说明,做为对上篇文章的补充. 阅读目录 动态改变属性序列化名称 枚举值序列 ...

  6. Jquery remove 高级用法

    Jquery remove 高级用法 html 代码 <div class="file-image">abc1111</div><div class= ...

  7. Newtonsoft.Json高级用法(转)

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  8. redis(二)高级用法

    redis(二)高级用法 事务 redis的事务是一组命令的集合.事务同命令一样都是redis的最小执行单元,一个事务中的命令要么执行要么都不执行. 首先需要multi命令来开始事务,用exec命令来 ...

  9. 【转】 Newtonsoft.Json高级用法

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

随机推荐

  1. python语法基础-并发编程-进程-进程锁和进程间通信

    ###############   守护进程  ############## """ 守护进程 父进程中将一个子进程设置为守护进程,那么这个子进程会随着主进程的结束而结束 ...

  2. Java之多线程窗口卖票问题(Thread)

    /** * * 例子:创建三个窗口卖票,总票数为100张.使用继承Thread类的方式 * * 存在线程的安全问题,待解决. * */class Window extends Thread{ priv ...

  3. drf序列化单改-整改-局部改-群改接口的实现

    整体单改 路由层.模型层.序列化层不需要做修改,只需要处理视图层:views.py """ 1) 单整体改,说明前台要提供修改的数据,那么数据就需要校验,校验的数据应该在 ...

  4. Junit单元测试、反射、注解

    Junit单元测试: * 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具体的执行流程. * Junit使用:白盒测试 * 步 ...

  5. Java8必知必会

    Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及 java.util.stream 包. 流(stream)就如同迭代器(iterator),但附 ...

  6. [Algo] 223. Add Two Numbers

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  7. cmake target_link_libraries() 中<PUBLIC|PRIVATE|INTERFACE> 的区别

    如果目标的头文件中包含了依赖的头文件(源文件间接包含),那么这里就是PUBLIC 如果目标仅源文件中包含了依赖的头文件,那么这里就是PRIVATE 如果目标的头文件包含依赖,但源文件未包含,那么这里就 ...

  8. is,数据类型补充,set,深浅拷贝

    十二.基础数据类型补充: 1.join 可以把列表变成字符串. s = ‘abc’ s1 = s.join(‘非常可乐’) print(s1)  #非abc常abc可abc乐abc s = " ...

  9. Flink(五) —— DataStream API

    Source 从自定义的集合中读取数据 /** * 从集合中读取数据 */ def readDataFromCollection(): Unit = { val env = StreamExecuti ...

  10. 为什么wget只下载某些网站的index.html? wget --random-wait -r -p -e robots=off -U mozilla http://www.example.com wget 下载整个网站,或者特定目录

    wget -c -r -np -k -L -p http://blog.hesheyou.me -c, –continue 接着下载没下载完的文件 -r, –recursive 递归下载 -np, – ...