识别在上下文菜单中选择的视图(Android)

识别在上下文菜单中选择的视图(Android),android,Android,在Android中,onContextItemSelected有一个MenuItem参数,因此不清楚如何识别所选视图。提供对的访问,但尽管两个已知子类都提供对目标视图的访问,但接口上似乎没有访问器 一种替代方法是将onCreateContextMenu中提供的视图保存在私有类变量中,该变量依赖于onCreateContextMenu在onContextItemSelected之前的活动中不再调用。另一种方法是对的itemId参数使用视图的id。如果我们这样做,那么我们将需要通过使用上下文菜单(可

在Android中,
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;
}