2013-03-29 43 views
4

基本上,我想在用户在网格视图中单击或长按单元格时显示不同的上下文菜单。我遇到的问题是,如果用户短时间点击OnItemClick侦听器,并且我看到调试器到达显示上下文菜单的代码,但不是从那里移动到onCreateContextMenu,而是转到onItemLongClick。Android GridView OnItemLongClick侦听器在OnItemClick之后调用

我已经尝试过使用布尔值来防止正在执行的长时间点击代码,它会阻止代码被执行,但是即使完成了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);  

      } 
     }); 

回答

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

+0

这完全解决了我的问题。我所要做的只是完全删除onItemLongClick监听器,并使用下面的代码来获取onContextItemSelected()中的选定单元格: – collusionbdbh

+0

AdapterView.AdapterContextMenuInfo info =(AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); \t mSelectedCell =(myCellClass)info.targetView; – collusionbdbh

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检查布局中可点击和可长按属性是否为“true”。

+0

!不起作用,因为代码在侦听器之外,它只会在侦听器设置时执行,而不是在实际执行时执行。我的布局是动态设置的,当创建布局时,我已经在代码中设置了这些属性。不管怎么说,还是要谢谢你。 – collusionbdbh

0

您可以在此改变调度事件监听器是resposible为长按操作

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

} 
+0

显然不起作用。当达到该代码时,clickFlag从未被修改过。 – njzk2

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,那么它会尝试创建上下文菜单。

所以,你需要修改你的回报声明onItemLongClick(你的代码没有显示)返回真正,如果它是很长的点击,并,如果它只是点击:

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

我试过这个,出于某种原因它导致了一些奇怪的行为,onItemLongClick被重复调用并且看起来无止境的,似乎它可能会在我的网格视图中为每个单元格调用一次。我绝对不明白它在做什么。 – collusionbdbh

相关问题