RecyclerView
アダプタを使用してアクティビティ内のデータを表示します。アクティビティ内にonClickListener
を実装したいのですが、現在、アダプタ内でonClickListener
を通常どおり設定しています。
public void onBindViewHolder(MyHolder holder, final int position) {
final Listdata data = listdata.get(position);
holder.vname.setText(data.getName());
holder.vname.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
});
}
ただし、アクティビティ内に実装したいので、より細かく制御できます。これは私の目的に役立ちません。私たちの多くにとって有用だと思います。
目的の動作を実現する方法を理解するには、ここで このチュートリアル を確認する必要があります。
アクティビティからonClickListener
を処理する場合、インターフェイスを使用したコールバック実装に基づいて作業する必要があります。アクティビティからインターフェイスをアダプタに渡し、いくつかのアイテムがクリックされたときにアダプタからコールバック関数を呼び出します。
これがチュートリアルのサンプル実装です。
まずインターフェースを用意しましょう。
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
アダプターを変更して、リスナーを以下のようなパラメーターとして使用する必要があります。
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
onBindViewHolder
メソッドで、クリックリスナーを設定します。
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
...
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
RecyclerView
にアダプターを設定します。
recycler.setAdapter(new ContentAdapter(items, new ContentAdapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));
したがって、アダプターコード全体は次のようになります。
public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
@Override public int getItemCount() {
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private TextView name;
private ImageView image;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
image = (ImageView) itemView.findViewById(R.id.image);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
name.setText(item.name);
Picasso.with(itemView.getContext()).load(item.imageUrl).into(image);
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
}
非常にシンプルでクリーンなソリューションは次のとおりです。
create a class with the name of RecyclerTouchListener:
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final 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 onClick(View view, int position);
void onLongClick(View view, int position);
}
}
recyclerviewアクティビティで:
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
speech(countries_list_code[position]);
}
@Override
public void onLongClick(View view, int position) {
}
}));
超簡単な方法を見つけました!私はこれをお勧めします
サンプルコード:
public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
@Override public int getItemCount() {
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private TextView name;
private ImageView image;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
image = (ImageView) itemView.findViewById(R.id.image);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
name.setText(item.name);
Picasso.with(itemView.getContext()).load(item.imageUrl).into(image);
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
}
そして、以下のコードを使用してRecyclerViewアダプタを使用します:
recycler.setAdapter(new ContentAdapter(items, new ContentAdapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));
私はこれを here から見つけました
お役に立てば幸いです。
私が正しく理解していれば、アクティビティのクリック時のロジックを設定したいと思います。
これを行うには、ActivityでOnClickListenerを設定し、Adapterコンストラクターに渡します。
MyAdapter myAdapter = new MyAdapter(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
}));
そして、MyAdapterコンストラクターは次のようになります。
final private OnClickListener onClickListener;
public MyAdapter(OnClickListener onClickListener) {
this.OnClickListener = OnClickListener;
}
新しいコードは次のようになります
public void onBindViewHolder(MyHolder holder, final int position) {
final Listdata data = listdata.get(position);
holder.vname.setText(data.getName());
holder.vname.setOnClickListener(onClickListener);
}
アダプタークラスのインターフェイスを作成する
private OnItemClickListener mListener;
public CustomAdapter(List<Listdata> listdata, OnItemClickListener listener) {
mListener = listener;
...
...
}
private class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ViewHolder(View view) {
...
...
view.setOnClickLister(this);
}
@override
public void onClick(View v) {
mListener.onAdapterItemClick(getAdapterPosition())
}
}
interface OnItemClickListener {
void onAdapterItemClick(int position);
}
アクティビティにインターフェースを実装させます
public class CustomListActivity extends AppCompatActivity implements OnItemClickListener {
...
...
@override
public void onAdapterItemClick(int position) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
これを行う別の方法があります。チェックアウト this implementation
Activity
に_View.OnClickListener
_を実装させ、アダプターに渡すことができます。以下に例を示します。
_class RAdapter extends RecyclerView.Adapter<>{
View.OnClickListener listner;
public RAdapter(View.OnClickListener listner) {
this.listner = listner;
}
public void onBindViewHolder(MyHolder holder, final int position) {
holder.vname.setOnClickListener(listner);
}
}
_
しかし、Activity
でクリックを処理するには、クリックされた位置が必要になります。 adapter.getAdapterPosition()
を使用して、クリックされたアイテムを検証できます。
それとは別に、すでにActivity
の参照がある場合は、アダプター内にOnClick
を保持し、アクションを実行する位置でActivity
のパブリックメソッドを呼び出すことができます。
ViewHolder
でクリックを処理するより良い方法。以下の例を参照してください。
_class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
Button button;
public Holder(View itemView) {
super(itemView);
button=itemView.findViewById(R.id.b1);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.b1){
int position=getAdapterPosition();
// Call a public method of Activity here
// with postion
}
}
}
_