【问题标题】:How to stop long clicks being handled as short click when no context menu shown如何在没有显示的上下文菜单时,单击即可停止单击单击
【发布时间】:2012-06-06 16:48:45
【问题描述】:

我有一个已为上下文菜单注册的列表视图。对于列表中的某些项目,上下文菜单不适用。在这些情况下,我只是不在 onCreateContextMenu 方法中扩充菜单。

不幸的是,这意味着当长按不显示上下文菜单的项目时,Android 会将其处理为短按(大概是因为上下文菜单通常会返回 true 表示长按事件已处理)。

这会导致列表视图中的行为不一致 - 当您长按某些项目时,它们会显示上下文菜单 - 其他项目则不会,然后执行默认的单击行为。如何确保即使不显示上下文菜单的项目也会使用长按,以免调用 onItemClick 方法?

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {

  AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
  Playable playable = (Playable) info.targetView.getTag(R.id.playable);
  if (playable != null && !(playable instanceof AutoRadioStation) && !(playable.getId().equals(Playlist.AUTOMATIC_PLAYLIST))) {
    v.setTag(R.id.playable, playable); // This copies the tag so that it is contained within the view used for the menu.
    Drawable stationImage = (Drawable) ((ImageView) info.targetView.findViewById(R.id.artwork)).getDrawable().getConstantState().newDrawable();

    menu.setHeaderTitle(playable.getName());
    menu.setHeaderIcon(stationImage);
    MenuInflater inflater = getActivity().getMenuInflater();
    inflater.inflate(R.menu.saved_context_menu, menu);
  }
}

【问题讨论】:

    标签: android listview contextmenu


    【解决方案1】:

    我遇到了类似的问题,最后我使用了 Dialog 而不是上下文菜单。

    我的活动实现了OnItemLongClickListener,如果满足条件,我会从onLongItemClick()显示出来。

    【讨论】:

    • 我对此进行了研究,因为这至少意味着我可以在所有情况下从 OnItemLongClick 返回 true。您必须创建自己的对话框还是有办法从 OnItemLongClickListener 调用列表视图的正常上下文菜单?
    • 我觉得不能直接触发上下文菜单,实现onCreateContextMenu的时候长按会显示。除非我错了,否则您必须创建对话框,这是一个相当简单的过程,您可以在我附加到我的答案的文档链接中看到
    【解决方案2】:

    我终于开始实施 NathanZ 解决方案的一个版本。似乎没有太多关于将 contextMenu 转换为 DialogFragment 的内容,所以我将在此处粘贴大部分解决方案。

    实现 onLongItemClick 侦听器还意味着我能够在列表视图中进行不需要菜单的长按事件。不幸的是,因为您不能将菜单传递给对话框,所以我不得不重用现有的 ListViewElement 类型来存储列表视图中每个“菜单”项的 id 和文本字符串。

      @Override
      public boolean onItemLongClick(AdapterView<?> parent, View view, int item, long position) {
    
        Playable playable = (Playable) view.getTag(R.id.playable);
        //Switch haptic feedback off by default so if we don't handle the long click we don't vibrate
        parent.setHapticFeedbackEnabled(false);
    
        if (playable == null) {
          // This must be a message bar so the only option is to update all saved content
          updateAll();
          parent.setHapticFeedbackEnabled(true);
        } else {
          if (!(playable instanceof AutoRadioStation) && !(playable.getId().equals(Playlist.AUTOMATIC_PLAYLIST))) {
            Drawable drawable = (Drawable) ((ImageView) view.findViewById(R.id.artwork)).getDrawable().getConstantState().newDrawable();
            showContextDialog(playable, drawable);
            parent.setHapticFeedbackEnabled(true);
          }
        }
        return true;
      }
      private void showContextDialog(Playable playable, Drawable drawable) {
        FragmentManager fm = getActivity().getSupportFragmentManager();
        final List<ListViewElement> array = new ArrayList<ListViewElement>();
        array.add(new ListViewElement(R.id.menu_share, null, getString(R.string.share), true));
        array.add(new ListViewElement(R.id.menu_delete, null, getString(R.string.delete), true));
        ContextMenuDialog dialog = new ContextMenuDialog(drawable, playable.getName(), array, playable);
        dialog.setOnItemClickListener(this);
        dialog.show(fm, "Context Menu");
      }
    
      //Callback from the ContextMenuDialog class
      @Override
      public void onItemClickDialogFragment(int option, Playable playable) {
        switch (option) {
          case R.id.menu_delete :
            // Perform delete actions
            break;
          case R.id.menu_share :
            // Perform share actions
            break;
        }
      }
    
    
    public class ContextMenuDialog extends DialogFragment implements OnItemClickListener {
    
      private Drawable drawableIcon;
      private String title;
      private List<ListViewElement> values;
      private Playable playable;
      private DialogFragmentOnItemClickListener listener;
    
      public interface DialogFragmentOnItemClickListener {
        void onItemClickDialogFragment(int option, Playable playable);
      }
    
      public void setOnItemClickListener(DialogFragmentOnItemClickListener listener) {
        this.listener = listener;
      }
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Create the dialog without a title since the layout includes a customized title
        setStyle(DialogFragment.STYLE_NO_TITLE, R.style.MyDialogStyle);
      }
    
      public ContextMenuDialog(Drawable drawableIcon, String title, List<ListViewElement> values, Playable playable) {
        this.drawableIcon = drawableIcon;
        this.title = title;
        this.values = values;
        this.playable = playable;
      }
    
    
      public ContextMenuDialog(int drawableResource, String title, List<ListViewElement> values, Playable playable) {
        this.drawableIcon = getResources().getDrawable(drawableResource);
        this.title = title;
        this.values = values;
        this.playable = playable;
      }
    
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.context_menu, container, true);
        TextView titleView = (TextView) view.findViewById(R.id.context_menu_title);
        titleView.setText(title);
        ImageView icon = (ImageView) view.findViewById(R.id.context_menu_artwork);
        icon.setImageDrawable(drawableIcon);
    
        ListView listView = (ListView) view.findViewById(R.id.context_menu_listview);
        ContextMenuAdapter adapter = new ContextMenuAdapter(getActivity(), R.layout.context_menu_list_item, values);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(this);
        return view;
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      相关资源
      最近更新 更多