Passing RecyclerView CardView Clicked Item Data To Activity

20,828

Solution 1

create an Interface inside your adapter containing methods. And while implementing your Adapter, those methods will be implemented in your activity and you can perform whatever action you want.

    public class Adapter extends RecyclerView.Adapter<MyRecycleViewHolder> {

    public interface Callbacks {
        public void onButtonClicked(String titleKey);
    }

    private Callbacks mCallbacks;

    public Adapter() {

    }

    @Override
    public MyRecycleViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_details, null);
        return new MyRecycleViewHolder(v);
    }

    @Override
    public void onBindViewHolder(final MyRecycleViewHolder holder, final int i) {

        holder.ExpandButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mCallbacks != null) {
                    mCallbacks.onButtonClicked(holder.ProbTitle.getText().toString());
                }
            }
        });

    }


    @Override
    public int getItemCount() {
        return;
    }

    public void setCallbacks(Callbacks callbacks) {
        this.mCallbacks = callbacks;
    }
}   

Solution 2

IMO, you implement setOnClickListener inside Adapter of RecyclerView. You can refer to my following sample code, then apply its logic to your code. Hope it helps!

public class MyRVAdapter extends RecyclerView.Adapter<MyRVAdapter.ViewHolder> {

    Context mContext;
    List<String> mStringList;

    public MyRVAdapter(Context mContext, List<String> mStringList) {
        this.mContext = mContext;
        this.mStringList = mStringList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TextView textView1 = (TextView) v.findViewById(R.id.textView1);
                TextView textView2 = (TextView) v.findViewById(R.id.textView2);
                Bundle bundle = new Bundle();
                bundle.putString("key1", textView1.getText().toString());
                bundle.putString("key2", textView2.getText().toString());

                passToAnotherActivity(bundle);
            }
        });
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // do something...
    }

    @Override
    public int getItemCount() {
        if (mStringList != null) {
            return mStringList.size();
        }
        return 0;
    }

    private void passToAnotherActivity(Bundle bundle) {
        if (mContext == null)
            return;
        if (mContext instanceof MainActivity) {
            MainActivity activity = (MainActivity) mContext;
            activity.passToAnotherActivity(bundle); // this method must be implemented inside `MainActivity`
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public ViewHolder(View itemView) {
            super(itemView);
            // do something...
        }

        @Override
        public void onClick(View v) {
        }
    }
}

Solution 3

you may try do this on your onItemClick()

Intent i = new Intent(view.getContext(), DetailsActivity.class); i.putExtra("title", yourTitle); i.putExtra("description", yourDescription); view.getContext().startActivity(i);

and when oncreate in your DetailActivity,do this

String title = getIntent().getStringExtra("title"); String description = getIntent().getStringExtra("description");

so you can pass title and description to DetailActivity

Solution 4

All above methods worked, but kinda long, so this one worked for me :

Cardview cardview;
            cardView = (CardView)itemView.findViewById(R.id.cv);

        cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent (view.getContext(), DetailsActivity.class);
                i.putExtra("TitleKey",ProbTitle.getText().toString());
                i.putExtra("DescrKey",ProbDescr.getText().toString());
                view.getContext().startActivity(i);
            }
        });

And in Details.java :

    TextView title;
TextView Descr;
        title = (TextView)findViewById(R.id.details_title);
    Descr = (TextView)findViewById(R.id.details_descr);

    String titleresult = result.getExtras().getString("TitleKey");
    String Descrresult = result.getExtras().getString("DescrKey");

    title.setText(titleresult);
    Descr.setText(Descrresult);

Solution 5

First of all make your "itemsdata" object to implement Parcelable. You can check it here . In your onItemClick method you pass the object to your Details activity using intent.putExtra("key",listOfDataItems.get(position)); In your DetailsActivity you can get your custom object with getParcelable("key")

Share:
20,828
Jaeger
Author by

Jaeger

Updated on April 20, 2020

Comments

  • Jaeger
    Jaeger about 4 years

    I have a question about passing clicked cardview data to activity, and here the full story :

    1. I have an Activity called "Details", which contains 2 TextViews in it's layout, Title & Description .

    2. I have setup a fragment ( tab_1 ) which contain the recyclerview codes and the the items data, each item of those contain : title & description .

    What i want :

    When the user click the item, it will open the Details Activity, and change Details layout title, with clicked item title, and the same for description .

    I've manged to create the other activity as an example, and made intent to start it, plus adding "addOnTouchlistener" thanks to Stackoverflow, i've found the way to make it .

    So, how to make this alive? I've tried many ways of the available answers on Stackoverflow, but all of them not working, or not related to my request .

    Here are my files :

    itemsdata.java :

    public class itemsdata {
    int CatPic;
    String title;
    String Descr;
    int Exapnd;
    int expand_no;
    

    tab_1.java ( fragment )

    public class tab_1 extends Fragment implements SearchView.OnQueryTextListener {
    
    private RecyclerView mRecyclerView;
    public RecyclingViewAdapter adapter;
    private Activity context;
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View layout = inflater.inflate(R.layout.tab_1, container, false);
        mRecyclerView = (RecyclerView)layout.findViewById(R.id.recycler_view);
        mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener
                (getContext(), new RecyclerItemClickListener.OnItemClickListener() {
    
                    @Override
                    public void onItemClick(View view, int position) {
                        Intent i = new Intent(view.getContext(), DetailsActivity.class);
                        view.getContext().startActivity(i);
                    }
                }));
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        adapter = new RecyclingViewAdapter(getActivity(),Listed());
        mRecyclerView.setAdapter(adapter);
        return layout;
    
    }
    
    
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.main, menu);
    
        final MenuItem item = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
        searchView.setOnQueryTextListener(this);
    }
    
    @Override
    public boolean onQueryTextChange(String query) {
        final List<itemsdata> filteredModelList = filter(Listed(), query);
        adapter.animateTo(filteredModelList);
        mRecyclerView.scrollToPosition(0);
        return true;
    }
    
    @Override
    public boolean onQueryTextSubmit(String query) {
        return true;
    }
    
    private List<itemsdata> filter(List<itemsdata> models, String query) {
        query = query.toLowerCase();
    
        final List<itemsdata> filteredModelList = new ArrayList<>();
        for (itemsdata model : models) {
            final String text = model.title.toLowerCase();
            if (text.contains(query)) {
                filteredModelList.add(model);
            }
        }
        return filteredModelList;
    }
    
    public List<itemsdata> Listed()
    {
        //Titles Strings
        String sys_title1 = getString(R.string.system_item_title_1);
        String sys_title2 = getString(R.string.system_item_title_2);
        String sys_title3 = getString(R.string.system_item_title_3);
    
        //Description Strings
        String sys_descr1 = getString(R.string.system_item_desc_1);
        String sys_descr2 = getString(R.string.system_item_desc_2);
        String sys_descr3 = getString(R.string.system_item_desc_3);
    
        //Adding New Cards
        List<itemsdata> data = new ArrayList<>();
    
        //Categories Icons New Items ** Make It The Same
        int[] icons = {
                R.drawable.facebook_icon ,
                R.drawable.twitter_icon ,
                R.drawable.twitter_icon
        };
    
        //Expand Button New Items
        int[] expandbutton = {
                R.drawable.expanded ,
                R.drawable.expanded ,
                R.drawable.expanded
        };
    
        //UnExpand Button New Items
        int[] unexpandbutton = {
                R.drawable.ca_expand ,
                R.drawable.ca_expand ,
                R.drawable.ca_expand
        };
    
        //Titles New Items
        String[] titles = {
                sys_title1 ,
                sys_title2 ,
                sys_title3
        };
    
        //Description New Items
        String[] Description = {
                sys_descr1 ,
                sys_descr2 ,
                sys_descr3
        };
    
    
        for(int i = 0;i<titles.length && i < icons.length  && i < Description.length && i < unexpandbutton.length && i < expandbutton.length  ; i++)
        {
            itemsdata current = new itemsdata();
            current.CatPic = icons[i];
            current.title = titles[i];
            current.Descr = Description[i];
            current.expand_no = unexpandbutton[i];
            current.Exapnd = expandbutton[i];
            data.add(current);
        }
        return data;
    }
    
    }
    

    Details Activity :

    public class DetailsActivity extends AppCompatActivity{
    
    TextView title;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.details);
        title = (TextView)findViewById(R.id.details_title);
    }
    

    EDIT : I've made it, i have added a button which open the fragment, and passed the data, in the Adapter, but i want it via tab_1.java, not the Adapter, i mean i want to click on the item to open the fragment, not on a button, here a snap from my Adapter code ( i've added it in OnBindViewHolder )

    I've setup a OnClick and implemented the Vew.setOnClick ..etc, but when i click the item, nothing happen.

     @Override
    public void onBindViewHolder(final MyRecycleViewHolder holder, int position) {
    
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(v.getContext(),DetailsActivity.class);
                v.getContext().startActivity(i);
            }
        });
    
        //Referencing Data
        final itemsdata currentobject = mdata.get(position);
        //Referencing Items
        holder.ProbTitle.setText(currentobject.title);
        holder.ProbDescr.setText(currentobject.Descr);
        holder.CategoryPic.setImageResource(currentobject.CatPic);
        holder.ExpandButton.setImageResource(currentobject.Exapnd);
        holder.ExpandNoButton.setImageResource(currentobject.expand_no);
            //What Happen When You Click Expand Button .
        holder.ExpandButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(v.getContext(), DetailsActivity.class);
                i.putExtra("TitleKey",holder.ProbTitle.getText().toString());
                v.getContext().startActivity(i);
                }
            }
        );
    
    public static class MyRecycleViewHolder extends RecyclerView.ViewHolder
    {
    
    
    
        SwipeLayout swipeLayout;
        //Defining Items .
        TextView ProbTitle;
        ImageButton ExpandButton;
        TextView ProbDescr;
        ImageButton ExpandNoButton;
        ImageView CategoryPic;
        /*
        TextView Card_Star;
        TextView Card_UnStar;
        */
        TextView Card_Share;
    
        //Referencing Resources
        public MyRecycleViewHolder(final View itemView) {
            super(itemView);
            ProbTitle = (TextView) itemView.findViewById(R.id.prob_title);
            CategoryPic = (ImageView) itemView.findViewById(R.id.cat_pic);
            ProbDescr = (TextView) itemView.findViewById(R.id.prob_descr);
            ExpandButton = (ImageButton) itemView.findViewById(R.id.expand_button);
            ExpandNoButton = (ImageButton) itemView.findViewById(R.id.expand_no_button);
            /*
            Card_Star = (TextView) itemView.findViewById(R.id.card_star);
            Card_UnStar = (TextView) itemView.findViewById(R.id.card_unstar);
            */
            Card_Share = (TextView) itemView.findViewById(R.id.card_share);
            swipeLayout = (SwipeLayout) itemView.findViewById(R.id.swipe);
    
        }
    
  • Jaeger
    Jaeger over 8 years
    Please check the edit, your way won't work, the problem in getting that string, only possible way is from the Adapter, but from the tab_1.java, it's not possible .
  • Jaeger
    Jaeger over 8 years
    if anyone didn't understand, my problem was in passing the clicked item title, so this worked for me, thanks a lot for your answers .
  • chichiangho
    chichiangho over 8 years
    @AboHani RecyclerView doesn't provide onItemClickListener and onItemLongClickListener,you should set it in adapter only...or you can create a interface in adapter like this public interface OnItemClickLitener { void onItemClick(View view, int position); void onItemLongClick(View view , int position); } and call it when each item clicked or long clicked,so you can set a listener in tab_1.java now.
  • Jaeger
    Jaeger over 8 years
    Yeah, I've added at first in this way, but i wasn't able to pass the data, anyway i've made it via referencing cardview in the adapter and passing the data using intent.putExtras . btw, if you have knowledge in searchview please check my question in my profile, and thanks for your answer :) .
  • chichiangho
    chichiangho over 8 years
    @AboHani every class that extend from View can set an onClickListener(),so just set this listener to your item's root view,no need to add a new button. and change this linei.putExtra("TitleKey",holder.ProbTitle.getText().toStrin‌​g()); toi.putExtra("TitleKey",currentobject.title); `
  • AJW
    AJW almost 7 years
    what is "result" above that you use with getExtras().getString()?
  • AJW
    AJW almost 7 years
    Is it used with "Intent result = getIntent()"?
  • Jaeger
    Jaeger almost 7 years
    Yes, its used with getIntent();