RecyclerViewにコンテキストメニューを作成する方法
registerForContextMenu(recyclerView)`を呼び出してもうまくいかないようです。フラグメントから呼び出しているのですが。誰かこの実装に成功した人はいますか?
89
20
registerForContextMenu(recyclerView)`を呼び出してもうまくいかないようです。フラグメントから呼び出しているのですが。誰かこの実装に成功した人はいますか?
情報とコメントありがとう。Recyclerview
のアイテムの
ContextMenu`を実現できました。以下は私がやったことです。
Fragment'の
onViewCreated
メソッドまたは Activity'sonCreate
メソッドで実行した:次にアダプタに
ViewHolder
クラスに
OnCreateContextMenuListener` を実装します。onBindViewHolder
メソッドにコンテキストメニューが読み込まれる前の位置を捕捉するために、holder.itemViewに
OnLongClickListener`を追加する:そして、
onViewRecycled
で、参照の問題がないようにListenerを削除する。(必要ないかもしれません)。最後に、フラグメント/アクティビティで
onContextItemSelected
を以下のようにオーバーライドする:onClickListenerやOnContextMenuListenerなどのメソッドを直接実装することはできません、 RecycleViewはandroid.view.ViewGroupを継承しているためです。そのため、これらのメソッドを直接使用することはできません。 これらのメソッドはViewHolder**アダプタクラスで実装できます。 このように、RecycleViewでコンテキストメニューを使うことができます:
同じ手順でコンテキストメニューを実装します。
何か困ったことがあればコメントで聞いてください。
現在の答えは正しくありません。 これが実用的な実装です。
フラグメント(またはアクティビティ):
そして最後に、ViewHolderで:
これをrecycleViewの「View」アイテムに試してください。
ViewHolder
アイテムにデータを設定すると使用できます。Prabhakar answerは正しいですが、コンテキストメニュー項目が選択されたときに、押された項目に関連するデータを取得する方法については説明しませんでした。
onContextItemSelected
コールバックを使用できますが、この場合はContextMenuInfo
は使用できません(null
)(getContextMenuInfo()
メソッドが押されたビューでオーバーライドされていない場合)。 したがって、最も簡単な解決策は、「OnMenuItemClickListener」を「MenuItem」に直接追加することです。@Renaudの回答は私にはうまくいきましたが、最初にいくつかのコード修正が必要でした。 それは彼がコードのいくつかの異なる反復からスニペットを投稿したようなものです。 行う必要がある変更は次のとおりです。
-
RecyclerContextMenuInfo
とRecyclerViewContextMenuInfo
は同じクラスです。 名前を選んで固執してください。 -ViewHolder
はView.OnLongClickListener
を実装する必要があり、コンストラクターのアイテムにsetOnLongClickListener()
を呼び出すことを忘れないでください。 -onLongClick()
リスナーでは、getView().showContextMenu()
は完全に間違っています。ContextMenuRecyclerView
でshowContextMenuForChild()
を呼び出す必要があります。そうしないと、onCreateContextMenu()
とonContextItemSelected()
で表示されるContextMenuInfo
がnullになります。以下の私の編集されたコード:
ContextMenuRecyclerView:
あなたのフラグメントで:
ViewHolderで:
また、レイアウトで「RecyclerView」を「ContextMenuRecyclerView」に置き換えるようにしてください。!
これが、私のために働いたコトリンでそれを行うためのより簡単な方法です。 主な課題は、押されたアイテムの位置を特定することです。 アダプター内にこのコードスニペットを配置すると、コンテキストメニューが表示されているアイテムの位置をキャプチャできます。それで全部です。
ソリューションと@Hardik Shahのソリューションを組み合わせました。
私が持っている活動では:
アダプターには:があります。
フラグメントには:があります。
パーティーに遅れるかもしれませんが、作業ソリューションがあります。 私はそれのために要点を作りました。
コンテキストメニューをリサイクルビューに追加。
ActivityName.java 。
RecyclerAdapter.java 。
これは、RecyclerViewアイテムのメニューコンテキストを使用するクリーンな方法です。
まず、アイテムの位置が必要です。
アダプタークラス:。
onBindViewHolder
でカスタムリスナーをフックします:。MainActivity(Activity / Fragment)でフィールドを作成します:。
アダプターオブジェクトでカスタムリスナーを設定します:。
次に、メニューを作成します。
解像度->メニュー。 メニュー項目
context_menu_main.xml
:のファイルを作成します。MainActivity:。
onCreateContextMenu
とonContextItemSelected
の両方を実装します。3番目に、アダプターオブジェクトに戻ります。
1。 コンテキストメニューを登録します。 2。 コンテキストメニューを表示します。
メニュードキュメントで詳細をご覧ください。
RecyclerViewのコンテキストメニューを実装し、コンテキストメニュー項目が選択されているアイテムの位置を取得する方法は次のとおりです。
}。
こんにちはみんな、私のために働く1つの代替案が登場しました。 itemViewをregisterContextMenu y the ViewHolder Constructorに登録するだけで、onLongClikcListenerも同じビューに設定できます。 onLongClick(View v)の実装では、getLayoutPosition()でクリックされた位置を取得し、インスタンス変数に保存します(ContextMenuInfoが機能すると予想されるのと同じように、このデータを表すクラスを作成しました)が、より重要なのは、 < b> false< / b>を返すようにします。この方法で。 今やらなければならないことは、onContextItemSelected(MenuItemアイテム)であなたの中にあり、インスタンス変数に保存したデータを読み、それが有効な場合はアクションを続行します。 これがスニペットです。
ViewHolderにOnLongClickListenerを実装させていますが、好きなように実行できます。
これをアダプター、またはViewHolderにある別のビュー(つまり、. テキストビュー)。 重要なのはonLongClik()の実装です。
最良の部分は、LongClickイベントを処理して、必要な場合にtrueを返すことができ、conextMenuが表示されないことです。
この方法は、registerForContextViewがView LongClickableを作成し、ContextMenuを処理するときに、システムがperformLongClickを呼び出すために機能します。これは、最初にonLongClick実装を呼び出し、falseを返す場合はshowContextMenuを呼び出します。
私はこのソリューションをしばらく使用しており、かなりうまく機能しています。。
フラグメントまたはアクティビティで、次のメソッドを実装します。。
最後に、recycleerviewのコンテキストメニューに登録します。
これでうまくいくはずです。!。
ListViewで非常にうまく機能していたRecyclerViewでは、Androidがこれをうまく処理できないため、私はこれに苦労しています。
最も難しいのは、ContextMenuInfoピースがビュー内に埋め込まれていることです。ビューをオーバーライドする以外は簡単に添付できません。
したがって、位置情報をアクティビティに配信するのに役立つラッパーが必要になります。
}。
次に、RecyclerAdapterでViewHoldersを作成するときに、ラッパーをルートビューとして設定し、各ビューにcontextMenuを登録する必要があります。
}。
そして最後に、あなたの活動では、あなたが通常行うことを行うことができます:
初めて通常のアダプターでこの問題に遭遇したとき、私は自分のカスタムビューサブクラスを作成し、必要なものを保存することになりました。 私は本当にその解決策が好きではなく、人々が提案した素晴らしいアイデアに多くの時間を費やし、私はそれらをもっと好きではないと決めました。 だから私はすべてをまとめて、しばらくそれを振り回して、好きな新しいものを手に入れました。
まず、いくつかのユーティリティクラスから始めます。 ContextMenuHandlerは、コンテキストメニューを処理するオブジェクトすべてに対するインターフェイスです。 実際には、これはViewHolderサブクラスになりますが、理論的には、ほぼ何でもかまいません。
次は、RecyclerViewの直接の子供として使用される任意のビューによって実装する必要があるインターフェイスです。
次に、RecylcerViewの子としてコンテキストメニューを作成するビューは、ViewWIthContextMenuを実装する必要があります。 私の場合、LinearLayoutのサブクラスしか必要ありませんでした。
そして最後に、コンテキストメニューの呼び出しを傍受して適切なハンドラーにリダイレクトするために、スープされたフラグメントクラスが必要です。
これらすべてが整っているため、最終的な実装は非常に簡単です。 メインフラグメントは、FragmentWithContextMenuをサブクラス化する必要があります。 メインRecylerWindowを正常にセットアップし、アダプターサブクラスに渡します。 アダプターサブクラスのようです。
それだけです。 それはすべて機能しているようです。 すべてのユーティリティクラスを個別のコンテキストメニューパッケージに配置したので、サブクラスがあるクラスに一致するクラス名を指定できましたが、もっと混乱すると思いました。
ContextMenu
を呼び出すときに**アイテムIDを取得したい人のためのソリューション。このようなアイテムが記載された「RecyclerView」がある場合(クリック可能な「ImageView」を含む):
。![リスト](https://i.stack.imgur.com/k1zgU.png。)。
次に、「onClickListener」からコールバックを受信する必要があります。
アダプター。
フラグメント。
警告。!。
1つのフラグメントに基づく「ViewPager」を使用する場合(すべてのページが類似のリストです)、問題が発生します。
onContextItemSelected
をオーバーライドして、選択したメニュー項目を理解すると、最初のページからリスト項目IDが取得されます。! この問題を克服するには、https://stackoverflow.com/questions/9753213/wrong-fragment-in-viewpager-receives-oncontextitemselected-callを参照してください。コンテキストメニューをリサイクラービューで使うには、カスタムのリサイクラービューを作成し、
getContextMenuInfo()
メソッドをオーバーライドして、コンテキストメニュー情報オブジェクトのインスタンスを返します:私が作成したgistをご覧ください:
https://gist.github.com/resengupta/2b2e26c949b28f8973e5
私の場合、「onContextItemSelected()」メソッドでフラグメントのデータを使用する必要がありました。 私が最終的に行った解決策は、フラグメントのインスタンスをアダプターに渡し、ビューアイテムをビューホルダーに登録することでした。
次に、
onCreateContextMenu()
でインデックスをローカル変数に保存できます。selectedViewIndex =(int)v.getTag();
。onContextItemSelected()
で取得します。上記の回答の一部を展開します。Adaptor/ ViewHolderのコードでメニューを手動で定義しないようにしたい場合は、PopupMenuを使用して、標準のmenu.xmlリソースファイルからメニューオプションを膨らませることができます。
以下の例は、フラグメント/アクティビティに実装してコンテキストメニューのクリックに応答できるリスナーに渡す機能を含むこれを示しています。
ここで完全な要点。 https://gist.github.com/brettwold/45039b7f02ce752ae0d32522a8e2ad9c。
バインド時にOnCreateContextMenuListenerをViewHolderに渡すことができます。 このリスナーは、データの各アイテムのカスタムメニューを作成できます。 ViewHolderにsetOnCreateContextMenuListenerを追加し、バインディング中に呼び出します。
}。
アダプターで: