简体   繁体   中英

Onclick to open activity from adapter of fragment not working

I am trying to run some code I got from some online tutorial of writing a fragment with a recyclerview in it but I am experiencing some difficulty in opening an activity from the onclick event. My adapter is below

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.MyViewHolder> {

    private final ArrayList<ItemModel> mArrayList;
    private Context mcontext;

    ItemAdapter(ArrayList<ItemModel> mArrayList) {
        this.mArrayList = mArrayList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        mcontext = parent.getContext();
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listing_item, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        //Glide.with(mcontext).load(mArrayList.get(position).getImage()).into(holder.item_image);

        holder.item_name.setText(mArrayList.get(position).getTitle());
        holder.item_description.setText(mArrayList.get(position).getDescription());
        holder.item_tags.setText(mArrayList.get(position).getTags());

        Log.d("MyAdapter", "position: " + position);
    }

    @Override
    public int getItemCount() {
        return mArrayList.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private final ImageView item_image;
        private final TextView item_name;
        private final TextView item_description;
        private final TextView item_tags;
        private final LinearLayout cardViewLayout;

        MyViewHolder(View view) {
            super(view);

            item_image = view.findViewById(R.id.item_image);
            item_name = view.findViewById(R.id.item_name);
            item_description = view.findViewById(R.id.item_description);
            item_tags = view.findViewById(R.id.item_tags);
            cardViewLayout = view.findViewById(R.id.cardViewLayout);
            cardViewLayout.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            Intent intent = new Intent(mcontext, ItemView.class);
            mcontext.startActivity(intent);
        }
    }
}

When I run the code nothing happens when i click on a item and neither do I see any error in the logcat

You can have a listener sent from the fragment to adapter. Instead of trying to start an activity from the adapter, you can send it back to the fragment to open the activity.

1. Define an interface

public interface MyAdapterListener {
   void openActivity(/*any values to be sent*/);
 }

2. The fragment should implement MyAdapterListener

3. send the listener object to an adapter in a constructor

ItemAdapter(ArrayList<ItemModel> mArrayList, MyAdapterListener listener) {..
         mListener = listener;
      }

4. On Adapter - View Holder: in onClick() return to fragment

public void onClick(View view) {
        mListener.openActivity(/*any values to be sent*/);
    }

Instead, try like this,

ItemAdapter(Context context, ArrayList<ItemModel> mArrayList) {
        this.mArrayList = mArrayList;
        this.mContext = context;
    }

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listing_item, parent, false);
    return new MyViewHolder(view);
}

In your fragment, while setting adapter

ItemAdapter itemAdapter=new ItemAdapter(getActivity(),itemList);

I was of the idea that on your application of the adapter in some activity you simply call the activity on the setOnItemClickListener of the adapter

private void loadItemsData() {
    RecyclerView itemsRecyclerView = view.findViewById(R.id.posts_recycler_view);
    itemsRecyclerView.setHasFixedSize(true);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
    itemsRecyclerView.setLayoutManager(layoutManager);

    ItemAdapter myadapter = new ItemAdapter(new ArrayList<MyItem>(), getContext());

    myadapter.setOnItemClickListener(new ItemAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(View view, PostItems items) {
            ViewItem.passingIntent(getActivity(), items.postid);
        }
    });

    itemsRecyclerView.setAdapter(ListAdapter );
}

then once done that you come to the receiver activity and make way to get the variables being passed on to it

public static void passingIntent(Activity activity, Integer postid){
    Intent intent = new Intent(activity, ViewItem.class);
    intent.putExtra(MY_ITEM, postid);
    activity.startActivity(intent);
}

I have used this approach in one of my apps lately

Try setting your click listener in onBindViewHolder like below

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    //Glide.with(mcontext).load(mArrayList.get(position).getImage()).into(holder.item_image);

    holder.item_name.setText(mArrayList.get(position).getTitle());
    holder.item_description.setText(mArrayList.get(position).getDescription());
    holder.item_tags.setText(mArrayList.get(position).getTags());

    holder.setOnClickListener(this) // put this line
    Log.d("MyAdapter", "position: " + position);
}

Then of course you will override onClick in adapter rather than viewholder

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM