を使用している人がに項目RecyclerView
を設定する方法を見つけましたか?各アイテムの各レイアウトにリスナーを設定することを考えましたが、それは少し面倒すぎるようです。イベントをリッスンする方法があると確信していますが、それを完全に理解することはできません。onClickListener
RecyclerView
RecyclerView
onClick
を使用している人がに項目RecyclerView
を設定する方法を見つけましたか?各アイテムの各レイアウトにリスナーを設定することを考えましたが、それは少し面倒すぎるようです。イベントをリッスンする方法があると確信していますが、それを完全に理解することはできません。onClickListener
RecyclerView
RecyclerView
onClick
回答:
APIが根本的に変更されたので、OnClickListener
アイテムごとにを作成しても驚かないでしょう。それほど面倒ではありませんが。の実装ではRecyclerView.Adapter<MyViewHolder>
、次のものが必要です。
private final OnClickListener mOnClickListener = new MyOnClickListener();
@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
view.setOnClickListener(mOnClickListener);
return new MyViewHolder(view);
}
onClick
方法:
@Override
public void onClick(final View view) {
int itemPosition = mRecyclerView.getChildLayoutPosition(view);
String item = mList.get(itemPosition);
Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
}
onClick()
、所属にOnClickListener
応じて任意のビューにアタッチできます。ここでの質問全体はどれですか!努力をしてください、メソッドは名前だけでなく少なくともクラスによっても識別されます。コードをアダプターに追加することを言わない場合、答えは実際には役に立ちません。
これは、OnClickListener
for を実装するためのより適切であまり密結合されていない方法RecyclerView
です。
使用法の抜粋:
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
// do whatever
}
@Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
RecyclerItemClickListener
実装:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
この方法で、過度のクラス、検出器などを使用せずに実行します。アダプター内の単純なコード。以前に提示されたものよりもlongClickの特に優れたソリューション。
public class PasswordAdapter extends RecyclerView.Adapter<PasswordAdapter.ViewHolder> {
private static ClickListener clickListener;
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView name;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
name = (TextView) itemView.findViewById(R.id.card_name);
}
@Override
public void onClick(View v) {
clickListener.onItemClick(getAdapterPosition(), v);
}
@Override
public boolean onLongClick(View v) {
clickListener.onItemLongClick(getAdapterPosition(), v);
return false;
}
}
public void setOnItemClickListener(ClickListener clickListener) {
PasswordAdapter.clickListener = clickListener;
}
public interface ClickListener {
void onItemClick(int position, View v);
void onItemLongClick(int position, View v);
}
}
次に、フラグメントまたはアクティビティの内部で、次のように入力します。
PasswordAdapter mAdapter = ...;
mAdapter.setOnItemClickListener(new PasswordAdapter.ClickListener() {
@Override
public void onItemClick(int position, View v) {
Log.d(TAG, "onItemClick position: " + position);
}
@Override
public void onItemLongClick(int position, View v) {
Log.d(TAG, "onItemLongClick pos = " + position);
}
});
同様のチェックアウト質問 CommonsWareさん@へのコメントリンクこの実装し、OnClickListener
中にインターフェイスをviewHolder
。
の簡単な例を次に示しViewHolder
ます。
TextView textView;//declare global with in adapter class
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView)view.findViewById(android.R.id.text1);
}
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
//go through each item if you have few items within recycler view
if(getLayoutPosition()==0){
//Do whatever you want here
}else if(getLayoutPosition()==1){
//Do whatever you want here
}else if(getLayoutPosition()==2){
}else if(getLayoutPosition()==3){
}else if(getLayoutPosition()==4){
}else if(getLayoutPosition()==5){
}
//or you can use For loop if you have long list of items. Use its length or size of the list as
for(int i = 0; i<exampleList.size(); i++){
}
}
}
次にAdapter
、次のようになります。
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
}
ListView
単純な行だけでなく、より複雑なオブジェクトのリストを作成する必要がある場合、これはすでに問題がありました。ListViewでアイテムをクリックした場所に応じて異なるイベントを処理する必要がある場合はどうなりますか?あなたはめちゃくちゃです。ここには、それぞれのリスナーがあります。
getPosition()
廃止予定です。使用するgetAdapterPosition()
か、getLayoutPosition()
代わりに使用してください。
Jacob Tabakの回答(彼の場合は+1)に基づいて、onLongClickリスナーを追加することができました。
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
その後、次のように使用できます。
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
// ...
}
@Override
public void onItemLongClick(View view, int position) {
// ...
}
}));
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
view.getId() == R.id.selection
これは私のために働いたものです。取り付けOnClickListener
にonBindView
。これがパフォーマンスに影響を与えるかどうかは本当にわかりませんが、小さなコードで問題なく動作するようです。
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "Recycle Click" + position, Toast.LENGTH_SHORT).show();
}
});
}
これは、アクティビティでアイテムクリックリスナーを使用すること、およびアイテムクリックリスナーでトリガーされないアイテムの単一ビューのクリックリスナーを使用することが非常に困難でした。Jacob Tabakの答えをいじった後、アイテム内の他のタッチアクションが表示されない場合、アイテムのクリックに対する彼の答えを尊重します。
カスタムがあります OnClickListener
クリックされたアイテムのビューとアダプターからのアイテムの位置を保持するアイテムクリックイベントを持つインターフェイスがあります。コンストラクター(またはセッターを使用することもできます)でそのインスタンスを提示し、ビューホルダーコンテナーのクリックリスナーにアタッチします。
アダプターからの他のクリックリスナーも持っています(ビューホルダーに含めることができます)。これは、コンテナーからの現在のビュークリックを処理します。
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {
private ArrayList<String> mData;
private OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
public MyRecyclerAdapter(ArrayList<String> itemsData,
OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
this.mData = itemsData;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View layoutView = LayoutInflater.from(mContext).inflate(
R.layout.list_item, parent, false);
final MyViewHolder viewHolder = new MyViewHolder(layoutView);
viewHolder.container.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(v, viewHolder.getAdapterPosition());
}
});
viewHоlder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//do button click work here with
// mData.get( viewHolder.getAdapterPosition() );
}
});
return viewHolder;
}
@Override
public int getItemCount() {
return mData.size();
}}
アクティビティでは、のインスタンスを渡してアダプターを初期化する必要があります OnItemClickListener
public class FeedActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
.....
MyRecyclerAdapter adapter = new MyRecyclerAdapter(new ArrayList<String>(), new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
///list item was clicked
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mFeedsAdapter);
}
そして私のビューホルダー
public class MyViewHolder extends RecyclerView.ViewHolder {
public Button button;
public View container;
public MyViewHolder(View itemLayoutView) {
super(itemLayoutView);
container = itemLayoutView;
button = (Button) itemLayoutView.findViewById(R.id.button);
}}
これは、誰かが便利だと思った場合に備えて、私が最終的に必要とするものです。
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View item) {
super(item);
item.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("RecyclerView", "onClick:" + getAdapterPosition());
}
});
}
}
出典:http : //blog.csdn.net/jwzhangjie/article/details/36868515
のアイテムとサブアイテムにRecyclerView
の良い解決策がonItemClickListener
あります
手順1-インターフェイスを作成する
public interface OnRecyclerViewItemClickListener
{
/**
* Called when any item with in recyclerview or any item with in item
* clicked
*
* @param position
* The position of the item
* @param id
* The id of the view which is clicked with in the item or
* -1 if the item itself clicked
*/
public void onRecyclerViewItemClicked(int position, int id);
}
ステップ2-次に、アダプターのonBindViewHolder
メソッドで次のように使用します
/**
* Custom created method for Setting the item click listener for the items and items with in items
* @param listener OnRecyclerViewItemClickListener
*/
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener)
{
this.listener = listener;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position)
{
// viewHolder.albumBg.setBackgroundResource(_itemData[position]
// .getImageUrl());
viewHolder.albumName.setText(arrayList.get(position).getName());
viewHolder.artistName.setText(arrayList.get(position).getArtistName());
String imgUrl = arrayList.get(position).getThumbImageUrl();
makeImageRequest(imgUrl, viewHolder);
viewHolder.parentView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
listener.onRecyclerViewItemClicked(position, -1);
}
});
viewHolder.settingButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
listener.onRecyclerViewItemClicked(position, v.getId());
}
});
}
// class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder
{
public TextView albumName, artistName;
public ImageView albumIcon, settingButton;
public LinearLayout parentView;
public ViewHolder(View itemLayoutView)
{
super(itemLayoutView);
// albumBg = (LinearLayout) itemLayoutView
// .findViewById(R.id.albumDlbg);
albumName = (TextView) itemLayoutView.findViewById(R.id.albumName);
artistName = (TextView) itemLayoutView
.findViewById(R.id.artistName);
albumIcon = (ImageView) itemLayoutView.findViewById(R.id.albumIcon);
parentView = (LinearLayout) itemLayoutView
.findViewById(R.id.albumDlbg);
settingButton = (ImageView) itemLayoutView
.findViewById(R.id.settingBtn);
}
}
ステップ3-これを使用しているアクティビティまたはフラグメントでリサイクラービューを見つけて設定する
recyclerView = (RecyclerView) rootview.findViewById(R.id.vmtopsongs);
lm = new LinearLayoutManager(mActivity);
lm.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(lm);
recyclerView.addItemDecoration(
new HorizontalDividerItemDecoration.Builder(getActivity())
.paint(Utils.getPaint()).build());
PopularSongsadapter mAdapter = new PopularSongsadapter(gallery,
mActivity, true);
// set adapter
recyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(this);
// set item animator to DefaultAnimator
recyclerView.setItemAnimator(new DefaultItemAnimator());
ステップ4-最後に、recyclerviewを使用しているアクティビティまたはフラグメントにインターフェイスを実装します
@Override
public void onRecyclerViewItemClicked(int position, int id)
{
if(id==-1){
Toast.makeText(mActivity, "complete item clicked", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(mActivity, "setting button clicked", Toast.LENGTH_LONG).show();
}
}
これが私がしたことです。このソリューションは、RecyclerViewアイテムとRecyclerViewアイテム内のビュー(内部ビュー)の両方でonClickとonLongClickの両方をサポートします。
私は選択したビューにviewHolderのタグを付けます:
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item, null);
ViewHolder viewHolder = new ViewHolder(itemView);
itemView.setOnClickListener( this);
itemView.setOnLongClickListener(this);
viewHolder.imageIV.setOnClickListener(this);
viewHolder.imageIV.setOnLongClickListener(this);
viewHolder.imageIV.setTag(viewHolder);
itemView.setTag(viewHolder);
return viewHolder;
}
そして、holder.getPosition()を使用してonClick()メソッドで位置を取得します(onLongClickも同様です)。
public void onClick(View view) {
ViewHolder holder = (ViewHolder) view.getTag();
int position = holder.getPosition();
if (view.getId() == holder.imageIV.getId()){
Toast.makeText(context, "imageIV onClick at" + position, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "RecyclerView Item onClick at " + position, Toast.LENGTH_SHORT).show();
}
}
getChildPositionを使用したバリアントも機能します。内部ビューの場合、onClick()で次のように使用することに注意してください:
int position = recyclerView.getChildPosition((View)view.getParent());
私の考えでは、このソリューションの利点は、画像をクリックするとonclick()画像リスナーのみが呼び出されるのに対し、RecyclerViewアイテムビューのJacobのソリューションと内部ビューのソリューションを組み合わせると、RecyclerViewアイテムビューonclick( )も呼び出されます(画像をクリックしたとき)。
これを行うにははるかに簡単な方法があります。クリックするだけで適用onBindViewHolder
ルートビューてです。
これがあなたのアダプターに対する見方であると考えてください、
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:textSize="15sp" />
</LinearLayout>
次に、アダプタで以下を実行します
//get the layout and make view holder
@Override
public RVAdapter.ViewHolder1 onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_layout, null);
ViewHolder1 viewHolder = new ViewHolder1(view);
return viewHolder;
}
@Override
public void onBindViewHolder(RVAdapter.ViewHolder1 holder, int position) {
//apply on click on your root view
holder.linearlayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Do on click stuff
}
});
}
//make references to views in layout including root view
public class ViewHolder1 extends RecyclerView.ViewHolder {
protected LinearLayout linearlayout = null
protected TextView textview = null;
public CareerLinksViewHolder(View itemView) {
super(itemView);
this.linearlayout = (LinearLayout) itemView.findViewById(R.id.linearlayout);
this.tvCompName = (TextView) itemView.findViewById(R.id.textview);
}
}
あなたは渡すことができますclickListener
にAdapter
。
あなたのActivity
:
private View.OnClickListener mItemClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = null;
int position = list.getChildPosition(v);
switch (position) {
case 0:
intent = new Intent(MainActivity.this, LeakCanaryActivity.class);
break;
case 1:
intent = new Intent(MainActivity.this, ButterKnifeFragmentActivity.class);
break;
}
if (intent != null) {
MainActivity.this.startActivity(intent);
}
}
};
次にそれを渡しますAdapter
:
MainAdapter mainAdapter = new MainAdapter(this, mItemClick);
中Adapter
さんonCreateViewHolder
:
@Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
View itemView = activity.getLayoutInflater().inflate(R.layout.main_adapter_item, viewGroup, false);
ViewHolder holder = new ViewHolder(itemView);
itemView.setOnClickListener(mItemClick);
return holder;
}
holder
意図を通して値をどのように渡しますか?
私はAndroid用の軽量ライブラリを開発しました。https://github.com/ChathuraHettiarachchi/RecycleClickにアクセスしてください。
次のサンプルをフォローしてください
RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// YOUR CODE
}
});
OnClickListenerをViewHolderクラスに実装できます
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public Item item
@InjectView(R.id.tv_title)
public TextView tvTitle;
@InjectView(R.id.rl_row)
public RelativeLayout rlRow;
public ViewHolder(View v) {
super(v);
ButterKnife.inject(this, v);
v.setOnClickListener(this);
}
@Override
public void onClick(View view) {
Log.e("item title",item.getTitle());
}
}
そしてonBindViewHolderはビューホルダーのアイテムを設定します
public void onBindViewHolder(ViewHolder holder, int position) {
holder.tvTitle.setText(objects.get(position).getTitle());
holder.item = objects.get(position);
}
あまりにも単純で効果的です。
View.OnClickListener
ビューホルダー内にインターフェースを実装したり、アクティビティにインターフェースを作成して実装したりする代わりに、シンプルなOnClickListener
実装にこのコードを使用しました。
public static class SimpleStringRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
// Your initializations goes here...
private List<String> mValues;
public static class ViewHolder extends RecyclerView.ViewHolder {
//create a variable mView
public final View mView;
/*All your row widgets goes here
public final ImageView mImageView;
public final TextView mTextView;*/
public ViewHolder(View view) {
super(view);
//Initialize it here
mView = view;
/* your row widgets initializations goes here
mImageView = (ImageView) view.findViewById(R.id.avatar);
mTextView = (TextView) view.findViewById(android.R.id.text1);*/
}
}
public String getValueAt(int position) {
return mValues.get(position);
}
public SimpleStringRecyclerViewAdapter(Context context, List<String> items) {
mBackground = mTypedValue.resourceId;
mValues = items;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
view.setBackgroundResource(mBackground);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mBoundString = mValues.get(position);
holder.mTextView.setText(mValues.get(position));
//Here it is simply write onItemClick listener here
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, ExampleActivity.class);
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mValues.size();
}
}
これまでに投稿されたすべての回答は優れたソリューションですが、あまり多くの実装の詳細を扱いたくない場合は、ListViewと同じように機能させたい場合は、次のようにTwoWay-Viewを使用することをお勧めします。
https://github.com/lucasr/twoway-view
この実装は、アイテムに対する長押し、および押された状態のサポートもサポートすることに注意してください(これは、この質問に対する他のソリューションにはない重要なものです)。
ライブラリ全体を使用したくない場合は、必要に応じてスタンドアロンとして使用できるClickItemTouchListenerクラスを確認してください。現時点で私が見つけた唯一の問題は、長押し+スクロールです。動作が正しくないようです。
個別のアイテムのクリックイベントをキャッチする場合はOnClickListener
、ViewHolder
クラスに実装してから、個々のビューまたは全体にクリックリスナーを設定しますitemView
。
次の例は同じことを示しています
public class ContactViewHolder extends RecyclerView.ViewHolder implements OnClickListener
{
TextView txt_title,txt_name,txt_email;
public ContactViewHolder(View itemView)
{
super(itemView);
txt_title = (TextView)itemView.findViewById(R.id.txt_title);
txt_name = (TextView)itemView.findViewById(R.id.txt_name);
txt_email = (TextView)itemView.findViewById(R.id.txt_email);
txt_name.setOnClickListener(this);
txt_email.setOnClickListener(this);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v == itemView)
{
Toast.makeText(RecyclerDemoActivity.this, "Visiting Card Clicked is ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
}
if(v == txt_name)
{
Toast.makeText(RecyclerDemoActivity.this, "Name ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
}
if(v == txt_email)
{
Toast.makeText(RecyclerDemoActivity.this, "Email ==>"+txt_email.getText(), Toast.LENGTH_SHORT).show();
}
}
}
}
私にとって、これは最良の方法です:
class YourRecyclerAdapter extends RecyclerView.Adapter<ContactViewHolder> implements View.OnClickListener {
...
@Override
public void onClick(View view) {
int itemPosition = vRecycle.getChildPosition(view);
//And use itemPosition to get the item from your collection. This way you dont restrain the ViewHolder with a OnClick callback
}
...
}
はありRecyclerView
ませんOnClickListener
自分で実装する必要があります。
からアイテムビューをクリックしたときに呼び出されるメソッドをOnItemClickListener
使用しAdapter
て、インターフェイスを追加しonClick
たいと思いますViewHolder
。したがって、アイテムのクリックを管理する責任はViewHolder
、Adapter
ます。何をすべきかを決定するアクティビティまたはフラグメント
リスナーとリスナーオブジェクトにインターフェイスを追加します。
public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> {
...
private static OnItemClickListener onItemClickListener;
...
public static interface OnItemClickListener {
public void onItemClick(View view, int position);
}
...
}
アイテムのルートビューのクリックと、コールバックがトリガーさonClick
れたときのアダプターのリスナー呼び出しをキャプチャします。
public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> {
...
private static OnItemClickListener onItemClickListener;
...
public static interface OnItemClickListener {
public void onItemClick(View view, int position);
}
...
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public ViewHolder(View itemRootView) {
super(itemRootView);
imageView = (ImageView) itemRootView.findViewById(R.id.itemImage);
itemRootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = ViewHolder.super.getAdapterPosition();
onItemClickListener.onItemClick(view,position);
}
});
}
}
}
アクティビティまたはフラグメント、ここではフラグメントなので、アダプターにリスナーを割り当て、onClickコールバックを使用して、位置によって選択されたアイテムを取得し、アイテムの詳細なアクティビティを開きます。
public class ItemsFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
((ItemsAdapter) adapter).setOnItemClickListener(new ItemsAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
//Do something when an item has been clicked
}
});
...
}
...
}
残念ながらRecyclerView
、ListView
組み込みの機能がいくつかありません。たとえばOnItemClickListener
、アイテムがクリックされたときにトリガーされるを追加する機能。
RecyclerView
を使用OnClickListener
してアダプタにを設定できますが、呼び出しコードからアダプタおよびにそのクリックリスナーを渡すことViewHolder
は、単純なアイテムのクリックをキャッチするために複雑です。
public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
};
private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnItemLongClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
return false;
}
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
= new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(View view) {
if (mOnItemClickListener != null) {
view.setOnClickListener(mOnClickListener);
}
if (mOnItemLongClickListener != null) {
view.setOnLongClickListener(mOnLongClickListener);
}
}
@Override
public void onChildViewDetachedFromWindow(View view) {
}
};
private ItemClickSupport(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mRecyclerView.setTag(R.id.item_click_support, this);
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}
public static ItemClickSupport addTo(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support == null) {
support = new ItemClickSupport(view);
}
return support;
}
public static ItemClickSupport removeFrom(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support != null) {
support.detach(view);
}
return support;
}
public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
return this;
}
public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClickListener = listener;
return this;
}
private void detach(RecyclerView view) {
view.removeOnChildAttachStateChangeListener(mAttachListener);
view.setTag(R.id.item_click_support, null);
}
public interface OnItemClickListener {
void onItemClicked(RecyclerView recyclerView, int position, View v);
}
public interface OnItemLongClickListener {
boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
}
}
R.id.item_click_support
ids.xmlを使用して定義する必要もあります。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="item_click_support" type="id" />
</resources>
結果のコードクリックリスナーは次のようになります。
ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// do it
}
});
recyclerviewのクリックに関する簡単な説明については、このlittlerobots_blogをご覧ください。
次のように、ViewHolderクラスでsetOnClickListenerを簡単に定義できます。
public class ViewHolder extends RecyclerView.ViewHolder {
TextView product_name;
ViewHolder(View itemView) {
super(itemView);
product_name = (TextView) itemView.findViewById(R.id.product_name);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int itemPosition = getLayoutPosition();
Toast.makeText(getApplicationContext(), itemPosition + ":" + String.valueOf(product_name.getText()), Toast.LENGTH_SHORT).show();
}
});
}
}
これが私がやったことです続きを読み、要点をここからダウンロードしてください
ここに同じものを追加する
CustomItemClickListener.java
public interface CustomItemClickListener {
public void onItemClick(View v, int position);
}
ItemsListAdapter.java
public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
ArrayList<ItemListSingleItem> data;
Context mContext;
CustomItemClickListener listener;
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
final ViewHolder mViewHolder = new ViewHolder(mView);
mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onItemClick(v, mViewHolder.getAdapterPosition());
}
});
return mViewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemTitle.setText(Html.fromHtml(data.get(position).getTitle()));
if (!TextUtils.isEmpty(data.get(position).getThumbnailURL())) {
// I Love picasso library :) http://square.github.io/picasso/
Picasso.with(mContext).load(data.get(position).getThumbnailURL()).error(R.drawable.ic_no_image).
placeholder(R.drawable.ic_no_image).
transform(new RoundedCornersTransformation(5, 0)).
into(holder.thumbnailImage);
} else {
holder.thumbnailImage.setImageResource(R.drawable.ic_no_image);
}
}
@Override
public int getItemCount() {
return data.size();
}
public ItemsListAdapter(Context mContext, ArrayList<ItemsListSingleItem> data, CustomItemClickListener listener) {
this.data = data;
this.mContext = mContext;
this.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView itemTitle;
public ImageView thumbnailImage;
ViewHolder(View v) {
super(v);
itemTitle = (TextView) v
.findViewById(R.id.post_title);
thumbnailImage = (ImageView) v.findViewById(R.id.post_thumb_image);
}
}
}
上記のほとんどの回答から、彼らはonclicklistenersを個々のアイテムに設定しているようです。ただし、提供しようとしているソリューションは非常にシンプルですが、多くの人にとって直感的ではありません。多くの人は、他のコンポーネントが常にリストビューまたはリサイクラービューでアイテムを表示するために使用される親コンポーネントにあることを忘れています。このソリューションは、単一のonclickリスナーをこの親ビューに設定するだけで、ターンが再生されます。ソリューションには、リストまたはリサイクラービューからクリックされているアイテムの位置を渡す方法も含まれています。ここで、メインのルートビューは、AndroidサポートライブラリのCardViewです。ここにサンプルコードがあります
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
public static final String LOG_TAG = ListAdapter.class.getSimpleName();
private Cursor mDataset;
private Context mContext;
private ViewHolder mViewHolder;
// Provide a suitable constructor (depends on the kind of dataset)
public ListAdapter(Context context, Cursor Dataset) {
mDataset = Dataset;
mContext = context;
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_business_view, parent, false);
mViewHolder = new ViewHolder(v);
return mViewHolder;
}
public void setData(Cursor newdata) {
this.mDataset = newdata;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//Bind data to other items here. To save time, i have ommited that.
//here is where we attach a click listerner for an item in the recycler list rather than for each element of a given item.
holder.card.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, " Just cliked item at position " + itemPosition, Toast.LENGTH_LONG).show();
}
});
}
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
if (null != mDataset) {
return mDataset.getCount();
}
return 0;
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder{
// each data item is just a string in this case
public final TextView mBusinesssName; // View for the business name
public final TextView mBusinessCategory; //View for the category name
public final ImageView businessImage; // View for the business category image Image
public final TextView mBusinessDistance; // View for the distance
public final CardView card;
public ViewHolder(View view) {
super(view);
mBusinesssName = (TextView) view.findViewById(R.id.list_item_name_textview);
mBusinessCategory = (TextView) view.findViewById(R.id.list_item_category_textview);
mBusinessDistance = (TextView) view.findViewById(R.id.list_item_dist_textview);
businessImage = (ImageView) view.findViewById(R.id.list_item_icon);
card = (CardView) view.findViewById(R.id.card_view);
}
}
}
mRecyclerView.addOnItemTouchListener(object : RecyclerItemClickListener(this, mRecyclerView,object :RecyclerItemClickListener.OnItemClickListener{
override fun onItemClick(view: View, position: Int) {
}
override fun onLongItemClick(view: View?, position: Int) {
}
}){})
RecyclerItemClickListener.java:
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
open class RecyclerItemClickListener(context: Context, recyclerView: RecyclerView, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {
private var mGestureDetector: GestureDetector
interface OnItemClickListener {
fun onItemClick(view: View, position: Int)
fun onLongItemClick(view: View?, position: Int)
}
init {
mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent): Boolean {
return true
}
override fun onLongPress(e: MotionEvent) {
val child = recyclerView.findChildViewUnder(e.x, e.y)
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child))
}
}
})
}
override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
val childView = view.findChildViewUnder(e.x, e.y)
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView))
return true
}
return false
}
override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, year, genre;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
genre = (TextView) view.findViewById(R.id.genre);
year = (TextView) view.findViewById(R.id.year);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, ""+getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
}
}
これが私のカスタムアダプタの完全なコードです。このコードは、「list_item」という名前のxmlファイルで定義されたリストアイテムで行を膨らませ、それぞれの位置ですべてのリストアイテム行でクリックイベントを実行します。
public class MyCustomAdapter extends RecyclerView.Adapter`<`AdapterMyCustomAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public onItemClickListener mListener;
public ViewHolder(View v, onItemClickListener listener) {
super(v);
mListener =listener;
v.setOnClickListener(this);
}
@Override
public void onClick(View v) {
mListener.onRecyclerItemClick(v, getPosition());
}
public static interface onItemClickListener {
public void onRecyclerItemClick(View view , int position);
}
}
@Override
public int getItemCount() {
return 5;
}
@Override
public void onBindViewHolder(ViewHolder holder, int pos) {
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
/* here list_item is an xml file we want to inflate ...it is same as we do in case of listview for customization.*/
MyCustomAdapter.ViewHolder vh = new ViewHolder(v, new MyCustomAdapter.ViewHolder.onItemClickListener() {
@Override
public void onRecyclerItemClick(View view, int position) {
System.out.println("clicked on list item at position " +position);
}
});
return vh;
}
}
これは、Javaの弱参照を使用して行うことができます。意味的には、ビューホルダーはクリックイベントに応答するか、適切なレスポンダーに委譲する必要があります。
私たちの目標:
手順:
クリック応答を処理するためのインターフェースを作成します。
クリックを処理するアクティビティにこのインターフェイスを実装します。
RecyclerViewアダプターにメンバー変数を追加して、弱参照とそれを設定するコンストラクターを保持します。
RecyclerView ViewHolderでも同じことを行い、メンバー変数を追加して位置を追跡します。
ViewHolderで任意のビューにクリックリスナーを設定し、レスポンダにコールバックしてそれらを処理します。
バインド時の位置を設定するようにonBindViewHolderメソッドを変更します。
レスポンダをViewHolderに渡します。
レスポンダでは、ビューでgetId()を使用して、クリックされたビューを特定できるようになりました。
そして、ここに要点がありますので、すべてがどのように組み合わされているかを確認できます: RecyclerViewクリック処理
たくさんの答えがあることは承知していますが、実装も提供できると思います。(詳細は、私が回答した別の質問で見つけることができます)。
したがって、クリックリスナーを追加するには、内部ViewHolder
クラスでを実装する必要がありますView.OnClickListener
。あなたが設定されますので、これはあるOnClickListener
にitemView
のパラメータViewHolder
のコンストラクタ。私が言っていることをお見せしましょう:
public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView text1, text2;
ExampleClickViewHolder(View itemView) {
super(itemView);
// we do this because we want to check when an item has been clicked:
itemView.setOnClickListener(this);
// now, like before, we assign our View variables
title = (TextView) itemView.findViewById(R.id.text1);
subtitle = (TextView) itemView.findViewById(R.id.text2);
}
@Override
public void onClick(View v) {
// The user may not set a click listener for list items, in which case our listener
// will be null, so we need to check for this
if (mOnEntryClickListener != null) {
mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
}
}
}
追加する必要のある他の唯一のものは、のカスタムインターフェイスAdapter
とセッターメソッドです。
private OnEntryClickListener mOnEntryClickListener;
public interface OnEntryClickListener {
void onEntryClick(View view, int position);
}
public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
mOnEntryClickListener = onEntryClickListener;
}
新しい、クリックをサポートする Adapter
が完成しました。
さあ、使ってみましょう...
ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects);
clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() {
@Override
public void onEntryClick(View view, int position) {
// stuff that will happen when a list item is clicked
}
});
基本的には、通常の設定方法です Adapter
作成したセッターメソッドを使用して、ユーザーが特定のリストアイテムをクリックしたときの動作を制御することを除いて、。
また、GitHubのこのGistで作成した一連の例を確認することもできます。
https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07
これは私が再利用することです OnClickListener
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyviewHolder>
implements View.OnClickListener
ViewHoderでitemlayoutの親を取得
public class MyviewHolder extends RecyclerView.ViewHolder {
LinearLayout linearLayout_item;
public MyviewHolder(View itemView) {
super(itemView);
linearLayout_item=itemView.findViewById(R.id.linearLayout_item);
}
}
onBindViewHolderでタグを位置として設定
@Override
public void onBindViewHolder(MyviewHolder holder, int position) {
holder.linearLayout_item.setTag(position);
holder.linearLayout_item.setOnClickListener(this);
}
そしてOnclick
@Override
public void onClick(View v) {
int position = (int) v.getTag();
switch (v.getId()) {
case R.id.linearLayout_item:
// do some thing with position
break;
}
}
私にとってそれを行うためのきれいな方法はこれです。
アダプターコンストラクター
private class EnvironmentTypeRecyclerViewAdapter extends RecyclerView.Adapter<EnvironmentTypeRecyclerViewAdapter.ViewHolder>
{
private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener;
private List<Environment> mEnvironmentsData;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public ViewHolder(View v)
{
super(v);
v.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
Environment environment = mEnvironmentsData.get(getAdapterPosition());
if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null) {
mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment);
}
}
public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener)
{
mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener;
mEnvironmentsData = environments;
}
}
リンクされたインターフェース
private interface EnvironmentTypeRecyclerViewAdapterListener
{
void onListItemSelected(Environment environment);
}