6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Android 9.0 Pie Java】RecyclerView 長押しで要素毎に内容の変わるコンテキストメニューを表示する

Last updated at Posted at 2020-08-30

RecyclerViewで要素を長押しして、要素毎に内容の変わるコンテキストメニューを表示する方法の記事が見当たらなかったのでメモしてみます!

↓完成イメージ↓
7c30d4aa9804094e0e83ddb1b9247cb8.gif

実装方法

コンテキストメニューの表示

Activity or Fragmentに

View.OnCreateContextMenuListener

をimplementsします。

SampleFragment.java
public class SampleFragment extends Fragment
        implements View.OnCreateContextMenuListener {

他にもViewHolderにimplementsするパターンもありますが、
コンテキストメニューを要素毎に内容を出し分けしたくて、都合のよかったFragmentにimplementsしました。

次に、RecyclerViewを生成をしているonCreatedViewメソッドで

SampleFragment.java
RecyclerView rv = view.findViewById(R.id.recyclerView);

// Adapter等のアタッチは省略します

registerForContextMenu(rv); // 追記

を追記します。
registerForContextMenuはView.OnCreateContextMenuListenerをimplementsすることで呼び出せるようになります。
この記述でコンテキストメニューを認識させることができます。

続いて、FragmentにonCreateContextMenuを実装します。

SampleFragment.java
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        // 長押しされたメッセージ位置を取得し、
        // RecyclerViewで表示させているListのindexとして扱い、
        // ユーザーIDを取得してメニューの出し分けを実現
        if (list.get(adapter.getPosition()).getUserId() == loginUserId) {
            menu.add(Menu.NONE, 1, Menu.NONE, "コピー");
            menu.add(Menu.NONE, 2, Menu.NONE, "編集");
            menu.add(Menu.NONE, 3, Menu.NONE, "削除");
        } else {
            menu.add(Menu.NONE, 1, Menu.NONE, "コピー");
        }
    }

ContextMenuオブジェクトに追加したい内容をaddする形で簡単に項目を追加できます。
addメソッドの第二引数に数値をセットしていますが、これは押された際のリスナーのハンドリングで使用します。
参考程度ですが、Adapterに以下の要領でgetPosition()メソッドを用意して、長押しされた要素の位置を取得できるようにしています。

Adapter.java
    @Override
    public void onBindViewHolder(final ChatViewHolder holder, int position) {

        // 省略

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                setPosition(holder.getPosition());
                return false;
            }
        });
    }

    // 長押しされた要素の位置を取得する
    public int getPosition() {
        return position;
    }

    // 長押しされた要素の位置をセットする
    public void setPosition(int position) {
        this.position = position;
    }

ここまでの実装でコンテキストメニューは表示できます。

コンテキストメニューのイベントリスナー

以下のように、onContextItemSelectedを実装し、中でswitch文を用いてハンドリングします。
MenuItem.getItemId()で先ほど登録した各要素の判別用の数値が取得できますので、
switch文で振り分ける感じですね。

SampleFragment.java
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 1:
                // TODO メッセージをクリップボードにコピー
                return true;
            case 2:
                // TODO メッセージを編集
                return true;
            case 3:
                // TODO メッセージを削除
                return true;
            default:
                return false;
        }
    }

以上です。

どなたかの参考になりましたら幸いです!!

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?