Android GridView OnItemLongClick listener called after OnItemClick

Basically, I want to show another context menu when the user clicks or long presses on a cell in the form of a grid. The problem is that if the short-click user calls the OnItemClick listener, and I see that the debugger reaches the code that shows the context menu, rather than moving from there to onCreateContextMenu, it goes to onItemLongClick.

I tried using Boolean to prevent the execution of long click code, which prevents the execution of this code, however even when it is done onCreateContextMenu is not called at all.

If I delete the onItemLongClick listener, then the short message listener works correctly and the context menu is displayed correctly.

I know that other people asked questions like this, but so far I have not been able to find a solution that works. If someone can solve this or point me in the right direction, please let me know, thanks in advance. A bounty will be awarded to anyone who can even point me in the right direction.

This is a simplified version of the code for listeners:

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
source share
5 answers

I understand that you want to show a different context menu for short clicks and long clicks on the GridView element.

First, you just need to set the listener for a short click, since by default the behavior automatically displays a context menu for long clicks.

Then set the boolean flag to true in OnItemClickListener. The default value for long clicks is false.

Finally, in onCreateContextMenu (), check if it has a short click and display another context menu (standard) and set the flag to false. Else allows you to display the default context menu (options).

Here is some code to demonstrate the idea.

 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]); } } } 

Sample application : You can download a sample application to see the behavior. GridExample_eclipse_project

+7
source

In a desperate situation, desperate decisions.

1. Try to work with booleans, instead of executing the code inside the listeners.

  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 check if both clickable and longclickable properties are “true” in your layout.

0
source

You can override the send event listener, which can be used to handle long clicks.

0
source
 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{} } 
0
source

OnItemLongClickListener launched because the context menu display for the ListView will try to do this through this listener. Here is the code from 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; } 

This shows that if mOnItemLongClickListener.onItemLongClick returns true, this means that the call has been processed and the method has completed. If it returns false, then it tries to create a context menu.

So, you need to change the return statement to onItemLongClick (which is not displayed by your code) to return true if it was pressed for a very long time, and false if it just clicked:

 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; } }); 
0
source

All Articles