1

コンテキスト メニューに登録されているリスト ビューがあります。リスト内の一部の項目では、コンテキスト メニューが適用されません。このような場合、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);
  }
}
4

2 に答える 2

1

同様の問題が発生しDialog、コンテキストメニューの代わりに使用することになりました。

私のアクティビティはを実装し、条件が満たされた場合OnItemLongClickListenerからそれを示し ます。onLongItemClick()

于 2012-06-01T13:19:52.663 に答える
1

最終的に、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;
 }
于 2012-08-01T08:45:02.223 に答える