Android
RecyclerView onClickListener
サーチ…
新しい例
public class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> {
private String[] mDataSet;
private OnRVItemClickListener mListener;
/**
* Provide a reference to the type of views that you are using (custom ViewHolder)
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View v) {
super(v);
// Define click listener for the ViewHolder's View.
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { // handle click events here
Log.d(TAG, "Element " + getPosition() + " clicked.");
mListener.onRVItemClicked(getPosition(),v); //set callback
}
});
textView = (TextView) v.findViewById(R.id.textView);
}
public TextView getTextView() {
return textView;
}
}
/**
* Initialize the dataset of the Adapter.
*
* @param dataSet String[] containing the data to populate views to be used by RecyclerView.
*/
public SampleAdapter(String[] dataSet) {
mDataSet = dataSet;
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.text_row_item, viewGroup, false);
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
// Get element from your dataset at this position and replace the contents of the view
// with that element
viewHolder.getTextView().setText(mDataSet[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataSet.length;
}
public void setOnRVClickListener(OnRVItemClickListener) {
mListener = OnRVItemClickListener;
}
public interface OnRVItemClickListener {
void onRVItemClicked(int position, View v);
}
}
KotlinとRxJavaの例
最初の例は、Kotlinで再実装され、RxJavaを使用してきれいな相互作用を実現します。
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.support.v7.widget.RecyclerView
import rx.subjects.PublishSubject
public class SampleAdapter(private val items: Array<String>) : RecyclerView.Adapter<SampleAdapter.ViewHolder>() {
// change to different subjects from rx.subjects to get different behavior
// BehaviorSubject for example allows to receive last event on subscribe
// PublishSubject sends events only after subscribing on the other hand which is desirable for clicks
public val itemClickStream: PublishSubject<View> = PublishSubject.create()
override fun getItemCount(): Int {
return items.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder? {
val v = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_row_item, parent, false);
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
}
public inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val textView: TextView by lazy { view.findViewById(R.id.textView) as TextView }
init {
view.setOnClickListener { v -> itemClickStream.onNext(v) }
}
fun bind(text: String) {
textView.text = text
}
}
}
使い方はとても簡単です。 RxJava機能を使用して別のスレッドで購読することも可能です。
val adapter = SampleAdapter(arrayOf("Hello", "World"))
adapter.itemClickStream.subscribe { v ->
if (v.id == R.id.textView) {
// do something
}
}
簡単なOnLongClickとOnClickの例
まず、ビュー所有者を実装します。
implements View.OnClickListener, View.OnLongClickListener
次に、次のようにリスナーを登録します。
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
次に、リスナーを次のようにオーバーライドします。
@Override
public void onClick(View v) {
onclicklistner.onItemClick(getAdapterPosition(), v);
}
@Override
public boolean onLongClick(View v) {
onclicklistner.onItemLongClick(getAdapterPosition(), v);
return true;
}
最後に、次のコードを追加します。
public void setOnItemClickListener(onClickListner onclicklistner) {
SampleAdapter.onclicklistner = onclicklistner;
}
public void setHeader(View v) {
this.headerView = v;
}
public interface onClickListner {
void onItemClick(int position, View v);
void onItemLongClick(int position, View v);
}
アダプタのデモ
package adaptor;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.wings.example.recycleview.MainActivity;
import com.wings.example.recycleview.R;
import java.util.ArrayList;
public class SampleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
private ArrayList<String> arrayList;
private static onClickListner onclicklistner;
private static final int VIEW_HEADER = 0;
private static final int VIEW_NORMAL = 1;
private View headerView;
public SampleAdapter(Context context) {
this.context = context;
arrayList = MainActivity.arrayList;
}
public class HeaderViewHolder extends RecyclerView.ViewHolder {
public HeaderViewHolder(View itemView) {
super(itemView);
}
}
public class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView txt_pos;
SampleAdapter sampleAdapter;
public ItemViewHolder(View itemView, SampleAdapter sampleAdapter) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
txt_pos = (TextView) itemView.findViewById(R.id.txt_pos);
this.sampleAdapter = sampleAdapter;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
onclicklistner.onItemClick(getAdapterPosition(), v);
}
@Override
public boolean onLongClick(View v) {
onclicklistner.onItemLongClick(getAdapterPosition(), v);
return true;
}
}
public void setOnItemClickListener(onClickListner onclicklistner) {
SampleAdapter.onclicklistner = onclicklistner;
}
public void setHeader(View v) {
this.headerView = v;
}
public interface onClickListner {
void onItemClick(int position, View v);
void onItemLongClick(int position, View v);
}
@Override
public int getItemCount() {
return arrayList.size()+1;
}
@Override
public int getItemViewType(int position) {
return position == 0 ? VIEW_HEADER : VIEW_NORMAL;
}
@SuppressLint("InflateParams")
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewType == VIEW_HEADER) {
return new HeaderViewHolder(headerView);
} else {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.custom_recycler_row_sample_item, viewGroup, false);
return new ItemViewHolder(view, this);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder.getItemViewType() == VIEW_HEADER) {
return;
} else {
ItemViewHolder itemViewHolder = (ItemViewHolder) viewHolder;
itemViewHolder.txt_pos.setText(arrayList.get(position-1));
}
}
}
上記のコード例は、次のコードで呼び出すことができます:
sampleAdapter.setOnItemClickListener(new SampleAdapter.onClickListner() {
@Override
public void onItemClick(int position, View v) {
position = position+1;//As we are adding header
Log.e(TAG + "ON ITEM CLICK", position + "");
Snackbar.make(v, "On item click "+position, Snackbar.LENGTH_LONG).show();
}
@Override
public void onItemLongClick(int position, View v) {
position = position+1;//As we are adding header
Log.e(TAG + "ON ITEM LONG CLICK", position + "");
Snackbar.make(v, "On item longclick "+position, Snackbar.LENGTH_LONG).show();
}
});
アイテムクリックリスナー
アイテムのクリックリスナーおよび/またはアイテムの長いクリックリスナを実装するには、アダプタでインターフェイスを作成します。
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemSeleted(int position, View view, CustomObject object);
}
public interface OnItemLongClickListener {
boolean onItemSelected(int position, View view, CustomObject object);
}
public final class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
final int position = getAdapterPosition();
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mOnItemClickListener != null) {
mOnItemClickListener.onItemSeleted(position, view, mDataSet.get(position));
}
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if(mOnItemLongClickListener != null) {
return mOnItemLongClickListener.onItemSelected(position, view, mDataSet.get(position));
}
}
});
}
}
private List<CustomObject> mDataSet;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
public CustomAdapter(List<CustomObject> dataSet) {
mDataSet = dataSet;
}
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.view_item_custom, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
// Bind views
}
@Override
public int getItemCount() {
return mDataSet.size();
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
public void setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClickListener = listener;
}
}
次に、アダプターのインスタンスを作成した後に、クリックリスナーを設定できます。
customAdapter.setOnItemClickListener(new CustomAdapter.OnItemClickListener {
@Override
public void onItemSelected(int position, View view, CustomObject object) {
// Your implementation here
}
});
customAdapter.setOnItemLongClickListener(new CustomAdapter.OnItemLongClickListener {
@Override
public boolean onItemSelected(int position, View view, CustomObject object) {
// Your implementation here
return true;
}
});
Item Click Listenerを実装する別の方法
項目のクリックリスナーを実装するもう1つの方法は、いくつかのメソッドを持つインターフェイスを使用することです。その数はクリック可能なビューの数と等しく、下に示すようにオーバーライドされたクリックリスナーを使用します。この方法は、クリックリスナを別々のビューに設定でき、クリックロジックを個別に個別に制御できるため、柔軟性があります。
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomHolder> {
private ArrayList<Object> mObjects;
private ClickInterface mClickInterface;
public interface ClickInterface {
void clickEventOne(Object obj);
void clickEventTwo(Object obj1, Object obj2);
}
public void setClickInterface(ClickInterface clickInterface) {
mClickInterface = clickInterface;
}
public CustomAdapter(){
mList = new ArrayList<>();
}
public void addItems(ArrayList<Object> objects) {
mObjects.clear();
mObjects.addAll(objects);
notifyDataSetChanged();
}
@Override
public CustomHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new CustomHolder(v);
}
@Override
public void onBindViewHolder(CustomHolder holder, int position) {
//make all even positions not clickable
holder.firstClickListener.setClickable(position%2==0);
holder.firstClickListener.setPosition(position);
holder.secondClickListener.setPosition(position);
}
private class FirstClickListener implements View.OnClickListener {
private int mPosition;
private boolean mClickable;
void setPosition(int position) {
mPosition = position;
}
void setClickable(boolean clickable) {
mPosition = position;
}
@Override
public void onClick(View v) {
if(mClickable) {
mClickInterface.clickEventOne(mObjects.get(mPosition));
}
}
}
private class SecondClickListener implements View.OnClickListener {
private int mPosition;
void setPosition(int position) {
mPosition = position;
}
@Override
public void onClick(View v) {
mClickInterface.clickEventTwo(mObjects.get(mPosition), v);
}
}
@Override
public int getItemCount() {
return mObjects.size();
}
protected class CustomHolder extends RecyclerView.ViewHolder {
FirstClickListener firstClickListener;
SecondClickListener secondClickListener;
View v1, v2;
public DialogHolder(View itemView) {
super(itemView);
v1 = itemView.findViewById(R.id.v1);
v2 = itemView.findViewById(R.id.v2);
firstClickListener = new FirstClickListener();
secondClickListener = new SecondClickListener();
v1.setOnClickListener(firstClickListener);
v2.setOnClickListener(secondClickListener);
}
}
}
また、アダプターのインスタンスがある場合は、各ビューをクリックしてリスニングするクリックリスナーを設定できます。
customAdapter.setClickInterface(new CustomAdapter.ClickInterface {
@Override
public void clickEventOne(Object obj) {
// Your implementation here
}
@Override
public void clickEventTwo(Object obj1, Object obj2) {
// Your implementation here
}
});
RecyclerViewクリックリスナー
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private RecyclerTouchListener.ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final RecyclerTouchListener.ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = 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 && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onLongClick(View child, int childPosition);
void onClick(View child, int childPosition);
}
}
MainActivityで
RecyclerView recyclerView =(RecyclerView) findViewById(R.id.recyclerview);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(),recyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onLongClick(View child, int childPosition) {
}
@Override
public void onClick(View child, int childPosition) {
}
}));
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow