识别在上下文菜单中选择的视图(Android)
在Android中,识别在上下文菜单中选择的视图(Android),android,Android,在Android中,onContextItemSelected有一个MenuItem参数,因此不清楚如何识别所选视图。提供对的访问,但尽管两个已知子类都提供对目标视图的访问,但接口上似乎没有访问器 一种替代方法是将onCreateContextMenu中提供的视图保存在私有类变量中,该变量依赖于onCreateContextMenu在onContextItemSelected之前的活动中不再调用。另一种方法是对的itemId参数使用视图的id。如果我们这样做,那么我们将需要通过使用上下文菜单(可
onContextItemSelected
有一个MenuItem
参数,因此不清楚如何识别所选视图。提供对的访问,但尽管两个已知子类都提供对目标视图的访问,但接口上似乎没有访问器
一种替代方法是将onCreateContextMenu
中提供的视图保存在私有类变量中,该变量依赖于onCreateContextMenu
在onContextItemSelected
之前的活动中不再调用。另一种方法是对的itemId
参数使用视图的id
。如果我们这样做,那么我们将需要通过使用上下文菜单(可能是国际化的)标题来识别从上下文菜单中选择的选项
识别onContextSelected
中选择的视图的最佳方法是什么?Android中的选项菜单或上下文菜单都没有“识别所选视图”这样的概念。因此,很难回答你的问题。所以,我来猜一猜
如果“标识所选视图”是指选择了哪个菜单选项,即传递给OnOptions ItemSelected()
或onContextItemSelected()
的getItemId()
菜单项
如果“标识所选视图”是指长时间点击列表视图中的哪一行以打开上下文菜单,请将getMenuInfo()
(在MenuItem
上调用)转换为AdapterView.AdapterContextMenuInfo
,然后根据您的适配器使用id
或position
值。它使用这种技术
如果“标识所选视图”是指在活动中有多个非列表视图
上下文菜单,我不会使用该UI技术。上下文菜单的全部要点是它与单个基础视图相关联,在Android中,关联在回调“onContextItemSelected”中丢失,这显然是一个设计限制。作为鼠标右键单击的替代方案,在任何足够大的视图上启用长时间触摸似乎是完全合理的
正如其他员额所建议的,在某些情况下:
AdapterView.AdapterContextMenuInfo menuInfo =
(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
是合适的,targetView是一个有用的参考点
另一种方法是对视图进行子类化,并重写“getContextMenuInfo”以提供视图引用。例如,一个简单的文本视图:
package ...;
public class TextViewWithContext extends TextView {
TextViewContextMenuInfo _contextMenuInfo = null;
public TextViewWithContext(Context context) {
super(context);
_contextMenuInfo = new TextViewContextMenuInfo(this);
}
public TextViewWithContext(Context context, AttributeSet attrs) {
super(context, attrs);
_contextMenuInfo = new TextViewContextMenuInfo(this);
}
protected ContextMenuInfo getContextMenuInfo() {
return _contextMenuInfo;
}
public boolean isContextView(ContextMenuInfo menuInfo) {
return menuInfo == (ContextMenuInfo)_contextMenuInfo;
}
protected class TextViewContextMenuInfo implements ContextMenuInfo {
protected TextView _textView = null;
protected TextViewContextMenuInfo(TextView textView) {
_textView = textView;
}
}
}
...
@Override
public boolean onContextItemSelected(MenuItem item) {
ContextMenuInfo menuInfo = item.getMenuInfo();
if (textViewWithContext.isContextView(menuInfo) {
...
}
}
包裹
公共类TextViewWithContext扩展了TextView{
TextViewContextMenuInfo\u contextMenuInfo=null;
公共文本视图与上下文(上下文){
超级(上下文);
_contextMenuInfo=新文本视图contextMenuInfo(此);
}
公共文本视图WithContext(上下文、属性集属性){
超级(上下文,attrs);
_contextMenuInfo=新文本视图contextMenuInfo(此);
}
受保护的ContextMenuInfo getContextMenuInfo(){
返回上下文菜单信息;
}
公共布尔值isContextView(ContextMenuInfo menuInfo){
返回menuInfo==(ContextMenuInfo)\u ContextMenuInfo;
}
受保护的类TextViewContextMenuInfo实现ContextMenuInfo{
受保护的文本视图_TextView=null;
受保护的TextViewContextMenuInfo(TextView TextView){
_textView=textView;
}
}
}
...
@凌驾
公共布尔值onContextItemSelected(MenuItem项){
ContextMenuInfo menuInfo=item.getMenuInfo();
if(textViewWithContext.isContextView(menuInfo){
...
}
}
最后,如果基本视图类为ContextInfo对象分配了一个对视图的反向引用,而不是像目前那样为空,则会更有帮助。类TestActivity扩展了活动{
// create temp item here
private ImageView tmpImageView = null;
我修复了一个类似的问题,根据发送菜单项的项目为菜单项设置groupID,例如:
textview.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
menu.setHeaderTitle("Context Menu");
menu.add(R.id.whateverviewclicked, RENAME_MENU_ITEM, 0, "Rename");
menu.add(R.id.whateverviewclicked, DELETE_MENU_ITEM, 1, "Delete");
}
});
这将允许您在onContextItemSelected中获取groupID:
public boolean onContextItemSelected(MenuItem aItem) {
int selectedViewID = aItem.getGroupId();
int selectedItem = aItem.getItemId();
};
你不必使用资源ID-你可以使用任何你想要的int。对我有用!如果你将ContextMenus附加到不在ListView中的多个视图(即视图下没有适配器),并且你想确定长按哪个视图访问ContextMenu,请执行以下“hack”可以实现。(如果Android提供一个可以与每个项目关联的侦听器会更好)
“黑客”是指在类中创建私有视图成员mLastViewTouched
,然后将以下onTouchListener附加到可以生成ContextMenu的所有视图:
private View.OnTouchListener onTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent)
{
mLastViewTouched = view; // Store a handle on the last view touched. This will be used to identify the view on which the Context Menu was launched
return false; // We return false since this indicates that the touch was not handled and so it is passed down the stack to be handled appropriately
}
};
因此,每当触摸视图时,都会更新MLASTVIEWMOOTED
。现在在onContextItemSelected
中,您将可以访问启动ContextMenu的视图。在OnCreateContextMenuListener
或onCreateContextMenu中构建菜单时(ContextMenu,View v,ContextMenu.ContextMenuInfo menuInfo)
实现中,您可以为每个项目设置自定义的MenuItem.OnMenuItemClickListener
:
addPhotosBtn.setOnCreateContextMenuListener((menu, v, menuInfo) -> {
getMenuInflater().inflate(R.menu.upload_image_menu, menu);
int itemCount = menu.size();
for(int i = 0; i < itemCount; i++) {
menu.getItem(i).setOnMenuItemClickListener(addPhotosBtnMenuItemClickListener);
}
});
addPhotosBtn.setOnCreateContextMenuListener((菜单,v,菜单信息)->{
getMenuInflater().充气(R.menu.upload\u image\u菜单,菜单);
int itemCount=menu.size();
对于(int i=0;i
由于此时您可以访问要为其创建上下文菜单的视图,因此可以将侦听器与该视图紧密耦合。以下是我为区分两个ListView lstA和lstB MenuItem所做的工作
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
int startid = (v.getId() == R.id.lstA) ? 0 : 2; //0-1 will be lstA and 2-3 will be lstB
menu.setHeaderTitle("some title");
menu.add(Menu.NONE, startid, Menu.NONE, "Item 1");
menu.add(Menu.NONE, startid+1, Menu.NONE, "Item 2");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int menuItemIndex = info.position;
switch(item.getItemId()) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
return true;
}
我指的是第三个选项,一般来说,屏幕上可能有多个视图,其中一些视图可能希望具有相同的上下文菜单。为什么不使用这种UI技术呢?Sim卡
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
int startid = (v.getId() == R.id.lstA) ? 0 : 2; //0-1 will be lstA and 2-3 will be lstB
menu.setHeaderTitle("some title");
menu.add(Menu.NONE, startid, Menu.NONE, "Item 1");
menu.add(Menu.NONE, startid+1, Menu.NONE, "Item 2");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int menuItemIndex = info.position;
switch(item.getItemId()) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
return true;
}