4

基本上,当用户短按或长按网格视图中的单元格时,我想显示不同的上下文菜单。我遇到的问题是,如果用户短按 OnItemClick 侦听器,我会看到调试器到达显示上下文菜单的代码,而不是从那里移动到 onCreateContextMenu,而是转到 onItemLongClick。

我尝试使用布尔值来防止执行长点击代码,这确实阻止了该代码的执行,但是即使这样做了 onCreateContextMenu 也不会被调用。

如果我删除 onItemLongClick 侦听器,则短击侦听器可以正常工作并且上下文菜单会正确显示。

我知道其他人提出了类似的问题,但我仍然无法找到有效的解决方案。如果有人可以解决这个问题或指出我正确的方向,请让我知道,在此先感谢。任何能够为我指明正确方向的人都将获得赏金。

这是听众代码的简化版本:

        mTGrid.setOnItemClickListener(new OnItemClickListener() {
            //this listener should show the context menu for a short click on the gridview.
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                    mRequiredMenu = "standard";
                    parent.showContextMenuForChild(v);      

            }
        });

        mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {
            //this listener should show the context menu for a long click on the gridview.
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                    mRequiredMenu = "options";
                        parent.showContextMenuForChild(v);      

            }
        });
4

5 回答 5

7

我了解您希望为 GridView 项目的短按和长按显示不同的上下文菜单。

首先,您只需为短按设置监听器,因为默认行为会在长按时自动显示上下文菜单。

接下来,在 OnItemClickListener 中将布尔标志设置为 true。长时间点击的默认值为 false。

最后,在 onCreateContextMenu() 检查它是否是一个短按并显示不同的上下文菜单(标准)并将标志设置为 false。否则让它显示默认的上下文菜单(选项)。

这是一些代码来演示这个想法。

public class MainActivity extends Activity {

    private static final String[] arr = {"A", "B", "C", "D", "E", "F", "G", "H","I"};

    private GridView mTGrid;
    private boolean isShort;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTGrid = (GridView) findViewById(R.id.gridView1);
        registerForContextMenu(mTGrid);

        mTGrid.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                isShort = true;
                openContextMenu(view);
            }
        });

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.cell, arr);
        mTGrid.setAdapter(adapter);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;

        if(isShort) {
            getMenuInflater().inflate(R.menu.context_standard, menu);
            menu.setHeaderTitle("Standard Menu for "+arr[info.position]);
            isShort = false;
        }
        else {
            getMenuInflater().inflate(R.menu.context_options, menu);
            menu.setHeaderTitle("Options Menu for "+arr[info.position]);
        }
    }   
}

示例应用程序:您可以下载示例应用程序以查看行为。GridExample_eclipse_project

于 2013-04-06T06:32:40.687 回答
0

对于绝境绝境的解决方案。

1.尝试使用布尔值,而不是在侦听器内执行代码。

 mTGrid.setOnItemClickListener(new OnItemClickListener() {
        //this listener should show the context menu for a short click on the gridview.
        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                b=true     
        }
    });

    mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {
        //this listener should show the context menu for a long click on the gridview.
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                b=false      
        }
    });
if(b)
{
     mRequiredMenu = "standard";
     parent.showContextMenuForChild(v);  
}
else
{
    mRequiredMenu = "options";
    parent.showContextMenuForChild(v);
}

2 检查布局中的可点击和长点击属性是否为“真”。

于 2013-04-04T13:23:40.023 回答
0

您可以覆盖调度事件侦听器,该侦听器负责长点击处理

于 2013-04-06T02:51:09.680 回答
0
mTGrid.setOnItemClickListener(new OnItemClickListener() {
            //this listener should show the context menu for a short click on the gridview.
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                     clickFlag=true;   
                     mRequiredMenu = "standard";                     

            }
        });

        mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {
            //this listener should show the context menu for a long click on the gridview.
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                     clickFlag=false;
                     mRequiredMenu = "options";                  
            }
        });

if(clickFlag){        
    if(mRequiredMenu.equals("standard");{
        //just click event
        parent.showContextMenuForChild(v);
    }else{}
}else{
   if(mRequiredMenu.equals("options");{
        //just Long click event
        parent.showContextMenuForChild(v);
    }else{} 

}
于 2013-04-06T04:49:52.590 回答
0

OnItemLongClickListener被触发,因为显示上下文菜单ListView将尝试通过该侦听器执行此操作。这是来自的代码AbsListView

@Override
public boolean showContextMenuForChild(View originalView) {
    final int longPressPosition = getPositionForView(originalView);
    if (longPressPosition >= 0) {
        final long longPressId = mAdapter.getItemId(longPressPosition);
        boolean handled = false;

        if (mOnItemLongClickListener != null) {
            handled = mOnItemLongClickListener.onItemLongClick(AbsListView.this, originalView,
                    longPressPosition, longPressId);
        }
        if (!handled) {
            mContextMenuInfo = createContextMenuInfo(
                    getChildAt(longPressPosition - mFirstPosition),
                    longPressPosition, longPressId);
            handled = super.showContextMenuForChild(originalView);
        }

        return handled;
    }
    return false;
}

从这里我们可以看出,如果mOnItemLongClickListener.onItemLongClick返回 true,则表示调用已处理,方法退出。如果它返回 false,那么它会尝试创建上下文菜单。

所以你需要修改你的return语句(你的代码没有显示)如果它真的被长时间点击onItemLongClick返回true ,如果它只是被点击则返回false

mTGrid.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {

        mRequiredMenu = "standard";
        mItemClicked = true;
        parent.showContextMenuForChild(v);
    }
});

mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {

        if(mItemClicked) {
            mItemClicked = false;
            return false;
        }

        mRequiredMenu = "options";
        parent.showContextMenuForChild(v);
        return true;
    }
});
于 2013-04-07T10:47:31.080 回答