Handle click item in Recycleview - android

I have a horizontal recycleview inside vertical recycleview.
and i add list cardview inside horizontal recycleview.
How to get the item information when click on the item on main activity?
Thank you
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private AlbumsVerticalAdapter adapter;
private List<Album> albumList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initCollapsingToolbar();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
albumList = new ArrayList<>();
adapter = new AlbumsVerticalAdapter(this, albumList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(adapter);
}
private void initCollapsingToolbar() {}
private void prepareAlbums() {}
}
public class AlbumsVerticalAdapter extends RecyclerView.Adapter<AlbumsVerticalAdapter.MyViewHolder> {
private Context mContext;
private List<Album> albumList;
//.............
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Album album = albumList.get(position);
holder.title.setText(album.getName());
AlbumsHorizontalAdapter itemListDataAdapter = new AlbumsHorizontalAdapter(mContext, albumList);
holder.recycler_view_list.setHasFixedSize(true);
holder.recycler_view_list.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
holder.recycler_view_list.setAdapter(itemListDataAdapter);
}
#Override
public int getItemCount() {
return albumList.size();
}
}

It would be better to implement OnClickListener on your ViewHolder class and add the listener to your desired views.
Just in onBindViewHolder(...) add setOnClickListener(...) like this:
#Override
public void onBindViewHolder(WordViewHolder holder, final int position) {
//...
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), position + "", Toast.LENGTH_SHORT).show();
}
});
}

Looking at your code the VerticalRecyclerViewAdapter has a List<Albums> and each Album in this list will require a HorizontalRecyclerViewAdapter to hold another List<Albums>.
In your VerticalRecylerViewAdapter create VerticalClickListener which will be implemented by your activity. Inside HorizontalRecyclerViewAdapter create HorizontalClickListener which will be implemented by your VerticalRecyclerViewAdapter for each Album. When creating the HorizontalRecyclerViewAdapter for each Album, pass in the vertical position as well. Then, when a cardview is clicked, the HorizontalClickListener can return the vertical position of the adapter and also the horizontal position of the cardview. The VerticalRecyclerViewAdapter will return the vertical and horizontal positions to your activity.

First, you create an interface like :
public interface OnItemClickListener{
void onItemClick(View view, int position)
}
Declare on global :
private OnItemClickListener mOnItemClickListener;
Next, you need a contructor like :
public MyAdapter(Context context, List data, OnItemClickListener mOnItemClickListener){
//...
this.mOnItemClickListener= mOnItemClickListener;
}
And in onBindViewHolder
#Override
public void onBindViewHolder(final FolderViewHolder holder, final int position) {
//....
holder.image.setOnClickListener(new View.OnItemClickListener){
#Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(v,position);
}
});
}
Finally, you can implement Callback in class use adapter like :
public class A extends AppCombatActivity implements MyAdapter.OnItemClickListener{
//exist code
#Override
onItemClick(View view, int position){
// Do something with view + position
}
}

/Just try to implement the below code Snippet/
First make an Interface Class "RecyclerView_ItemClickListener"
public interface RecyclerView_ItemClickListener
{
void onClick(View view, int position);
void onItemClick(View view, int position);
}
Then use this class in your Activity/Fragment and inside Adapter.
How to Implement in Adapter class:
private RecyclerView_ItemClickListener clickListener;
public void setClickListener(RecyclerView_ItemClickListener itemClickListener)
{
this.clickListener = itemClickListener;
}
public void SetOnItemClickListener(final RecyclerView_ItemClickListener mItemClickListener)
{
this.clickListener = mItemClickListener;
}
Implement implements View.OnClickListener inside MyViewHolder Method
of Adapter
Example like this: class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
itemView.setOnClickListener(this);
Then put the below code
#Override
public void onClick(View view)
{
if (clickListener != null)
{
clickListener.onClick(view, getAdapterPosition());
clickListener.onItemClick(view,getAdapterPosition());
}
}
After that implements RecyclerView_ItemClickListener inside your
Activity/Fragment
in OnCreate:
your_Adapter.setClickListener(this);
your_Adapter.SetOnItemClickListener(this);
#Override
public void onClick(View view, int position)
{}
#Override
public void onItemClick(View view, int position)
{
}

Create an inteface
public interface OnItemClickListener{
void onItemClick(View view, int position)
}
Add a parametrized constuctor in your adapter AlbumsVerticalAdapter
private OnItemClickListener mOnviewItemClickListener;
public AlbumsVerticalAdapter(Context context, List data, OnItemClickListener mOItemClickListener){
//...
this.mOnItemClickListener= mOnItemClickListener;
Now add this line in your in OnBinderViewHolder method inside adapter class
#Override
public void onBindViewHolder(final FolderViewHolder holder, final int position) {
//....
mholder.mimageview.setOnClickListener(new View.OnItemClickListener){
#Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(v,position);
}
});
}
Implement this interface in your Activity and use onClick of the item
public class MainActivity extends AppCombatActivity implements AlbumsVerticalAdapter.OnItemClickListener{
#Override
onItemClick(View view, int position){
// write your code
}
}

Related

how can I pass data from recyclerview click to a fragment which is inside the same activity in which my recyclerview is placed?

public void onBindViewHolder(#NonNull final myViewHolder holder, final int position) {
holder.tvItem.setText(itemList.get(position).getmTitle());
Picasso.get().load(itemList.get(position).geturl()).into(holder.imgFlag);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ModelClass model= itemList.get(position);
}
});
Here is an example you can follow this and fit as per your requirement-
Create an interface in your adapter
public interface OnItemClickListener {
void onItemClicked(int position, Object object);
}
in your adapter call
Adapter adapter = new Adapter(context, list, new Adapter.OnItemClickListener() {
#Override
public void onItemClicked(int position, Object object) {
// Handle Object of list item here
}
});
on your adapter
private OnItemClickListener onItemClickListener; // Global scope
in constructor call:
this.onItemClickListener = onItemClickListener;
on your item clicked event :
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListener.onItemClicked(position, _list.get(position));
}
});
You can use this one for single view and multiple view click
adapter viewholder class
public class MyViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
CircleImageView imgPlayer;
TextView playerRole;
public MyViewHolder(View itemView) {
super(itemView);
imgPlayer = itemView.findViewById(R.id.trnmt_player);
playerRole = itemView.findViewById(R.id.pRole_id);
playerRole .setOnClickListener(this);
imgPlayer.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == imgPlayer) {
onItemClickListener.onItemClicked(position,list.get(position));
} else if(v==playerRole){
}
}
}
}
interface
public interface OnItemClickListener {
void onItemClicked(int position, Object object);
}
inside adapter
private OnItemClickListener onItemClickListener;
It will be helpful if you provide some snapshot of your code.
Although you can get callback of click action on recycler view on your activity. So for this you need to create your own Listener and set to your Custom adapter.
Creation of a Action Listener
public interface ActionListener<T> {
void onClickAction(int positionOfItem, T object);//here T will be the type of object bound to your view.
}
Now create a method in your custom adapter to set this listener
private ActionListener mListener;
public void setActionListener(ActionListener listener){
mListener = listener;
}
Now use this listener to navigate the call back from your adapter.
public void onBindViewHolder(#NonNull final myViewHolder holder, final int position) {
holder.tvItem.setText(itemList.get(position).getmTitle());
Picasso.get().load(itemList.get(position).geturl()).into(holder.imgFlag);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ModelClass model= itemList.get(position);
listener.onClickAction(position, model);//this will pass the call to the listener.
}
});
}
Now set the listener to adapter in your activity class, where you just created the adapter instance. Here you need to invoke a method in your fragment. For getting the fragment you can use findFramgentById() or findFragmentByTag() methods.
adapter.setActionListener(new ActionListener<ModelClass>(){
void onClickAction(int positionOfItem, ModelClass object){
MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag();
fragment.updateActionData(object);
}
});
Please create a method in your fragment as given below :
public void updateActionData(ModelClass object){
//to do your work with object
}
Hope this will work.

Recycler View item on Click not working even after following the listener procedure

I am Trying to start an activity from a recycler view item and followed the procedures yet the onClick is not calling in my app. I have checked the hasOnClickListeners() and that returned true. please help me.
public class ShopAdapter extends
RecyclerView.Adapter<ShopAdapter.ViewHolder> {
public List<String> shopDetails;
public View view;
public Context context;
public ShopAdapter(List<String> shopDetails){
this.shopDetails = shopDetails;
}
#Override
public ShopAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_single,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ShopAdapter.ViewHolder holder, int position) {
final String shop_description_data = "ONE";
final String shop_name_data = "TWO";
holder.setShopNameView(shop_name_data);
holder.setShopInfoView(shop_description_data);
Here I have set the item click listener from view holder
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClicked(View view, int position) {
Log.d("GOUSE","on Item Click");
}
});
}
private void startShopActivity(String shop_name_data, String shop_description_data,View view) {
}
#Override
public int getItemCount() {
return shopDetails.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView shopDescView;
private TextView shopNameView;
private View mView;
private ItemClickListener onItemClickListener;
private CardView shopItem;
public ViewHolder(View itemView) {
super(itemView);
mView = itemView;
Here I set the on click listener to my listener interface
mView.setOnClickListener(this);
Log.d("Listener",mView.hasOnClickListeners()+"");
}
public void setShopInfoView(String shopDescText){
shopDescView = mView.findViewById(R.id.shop_info);
shopDescView.setText(shopDescText);
}
public void setShopNameView(String shopNameText){
shopNameView = mView.findViewById(R.id.shop_name);
shopNameView.setText(shopNameText);
}
public void startShop(String shopName,String shopDesc){
Intent shopActivityMainIntent = new Intent(mView.getContext(),MainActivity.class);
shopActivityMainIntent.putExtra("shopName",shopName);
shopActivityMainIntent.putExtra("shopDescription",shopDesc);
mView.getContext().startActivity(shopActivityMainIntent);
}
public void setItemClickListener(ItemClickListener itemClickListener){
Log.d("GOUSE","set item listener");
this.onItemClickListener = itemClickListener;
}
#Override
public void onClick(View view) {
Log.d("GOUSE","set item clicked");
onItemClickListener.onItemClicked(view,getAdapterPosition());
}
}
}
make some changes in adapter used interface to handle recycler view click event like below code ...
private onItemClickListener onItemClickListener;
/**
* this interface is used to handle recycler view click event.
*/
public interface onItemClickListener {
void onItemClick(Cricketer cricketer);
}
public void setOnItemClickListener(onItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
#Override
public void onBindViewHolder(#NonNull ItemViewHolder holder, final int position) {
final Cricketer cricketer = mCricketerList.get(position);
holder.mTvTitle.setText(cricketer.getName());
holder.mTvDescription.setText(cricketer.getCountry());
holder.mTvDate.setText(cricketer.getDateOfBirth());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListener.onItemClick(cricketer);
}
});
}
when you bind adapter into recycler view that time get click event like below code..
/**
* this method used to bind adapter into recycler view.
*/
private void setAdapter() {
recyclerViewAdapter = new RecyclerViewAdapter(this, mCricketerList);
mRvData.setAdapter(recyclerViewAdapter);
recyclerViewAdapter.notifyDataSetChanged();
recyclerViewAdapter.setOnItemClickListener(new RecyclerViewAdapter.onItemClickListener() {
#Override
public void onItemClick(Cricketer cricketer) {
Toast.makeText(getApplicationContext(), "Cricketer Name::" + cricketer.getName(), Toast.LENGTH_SHORT).show();
}
});
}

Update ArrayList for RecyclerView.Adapter from RecyclerView.ViewHolder?

In my MainActivity I have something like this:
recyclerAdapter = new RecyclerAdapter(this, arrayList);
recyclerView.setAdapter(recyclerAdapter);
To update my RecyclerView, I do: (in MainActivity, too)
Item item = new Item();
item.setId(id);
item.setMessage(message);
arrayList.set(position, item);
recyclerAdapter.notifyItemChanged(position);
I want to have a button within every RecyclerView list item which can enable/disable the current entry. Therefore I need to get the current toggle state.
My problem is, how can I update the RecyclerView in MainActivity from within my ViewHolder?
RecyclerView.ViewHolder:
public class SetViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{//, View.OnLongClickListener{
public ImageView toggle;
public SetViewHolder(View itemView){
super(itemView);
toggle = (ImageView) itemView.findViewById(R.id.img_main_card_toggle);
toggle.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.getId() == toggle.getId()) {
int clicked_position = getAdapterPosition();
//TODO update Item of RecyclerView of MainActivity
}
}
My Recycler.Adapter:
public class RulesAdapter extends RecyclerView.Adapter<SetViewHolder>{
private Activity activity;
List<Item> items = Collections.emptyList();
private OnTapListener onTapListener;
public RulesAdapter(Activity activity, List<Item> items){
this.activity = activity;
this.items = items;
}
#Override
public SetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rules_list_item,parent,false);
return new SetViewHolder(view);
}
#Override
public void onBindViewHolder(SetViewHolder holder, final int position) {
holder.recevied_message.setText(items.get(position).getReceived_message());
holder.reply_message.setText(items.get(position).getReply_message());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(onTapListener != null){
onTapListener.OnTapView(position);
}
}
});
}
#Override
public int getItemCount() {
return items.size();
}
public void setOnTapListener(OnTapListener onTapListener){
this.onTapListener = onTapListener;
}
}
Define an Interface.
public interface OnRecyclerItemToggleClickListener {
void onToggleClick(int adapterPosition);
}
Implement this in your adapter. And pass the adapter instance to the ViewHolder through a setter method in the onCreateViewHolder callback.
public class SetViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{//, View.OnLongClickListener{
public ImageView toggle;
private OnRecyclerItemToggleClickListener listener;
public SetViewHolder(View itemView){
super(itemView);
toggle = (ImageView)
itemView.findViewById(R.id.img_main_card_toggle);
toggle.setOnClickListener(this);
}
public void setRecyclerItemToggleClickListener( OnRecyclerItemToggleClickListener listener) {
this.listener = listener;
}
#Override
public void onClick(View v) {
if (v.getId() == toggle.getId()) {
int clicked_position = getAdapterPosition();
//TODO update Item of RecyclerView of MainActivity
listener.onToggleClick(clicked_position);
}
}
In your adapter:
#Override
public SetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rules_list_item,parent,false);
SetViewHolder holder = new SetViewHolder(view);
holder.setOnRecyclerItemToggleClickListener(this);
return holder;
}
#Override public void onToggleClick(int adapterPosition) {
// you will get the callback here when the toggle button is clicked.
// you can update the ArrayList here.
// Or similarly, call an interface method to Activity.
}
And call this onToggleClick method from ViewHolder when the toggle is clicked. You will get a callback to adapter, where you can update the ArrayList. Otherwise you can have another similar Interface to give callback to Activity from the adapter.
You just have to add a static function and make items static too:
public static ArrayList<Items> getAreayList()
{
return items;
}
And get this function in MainActivity:
onStart()

How do I set up a specific button in the recyclerView to send back the info to the MainActivity?

I have a RecyclerView that has a button that creates a TimePickerDialog, and I need send back the time picked to the MainActivity.
How do I send it back?(Not trough clicking the entire view, just from that button/dialog)
Make your RecyclerView's adapter implement a custom interface. It's the only reasonable and adequate way.
CODE:
RecyclerViewAdapter.java:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private ButtonListener mListener;
public interface ButtonListener {
void onButtonClick(View view, String yourInfo);
}
public void setButtonListener(ButtonListener listener) {
mListener = listener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
.....
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
.....
}
public class ViewHolder extends RecyclerView.ViewHolder {
private final Button mButton;
ViewHolder(View v) {
super(v);
mButton = (Button)v.findViewById(R.id.favouriteButton);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener != null)
mListener.onButtonClick(v, "Your info");
}
});
}
}
}
Activity.java:
private RecyclerViewAdapter mAdapter;
...
...
mAdapter = new RecyclerViewAdapter(yourParams...);
mAdapter.setButtonListener(new RecyclerViewAdapter.ButtonListener() {
#Override
public void onButtonClick(View view, String yourInfo) {
// Do stuff with yourInfo
}
});
Define the interface callback with the parameters that you need & that shall do it. This way you can intercept the RecyclerView items' click event and handle it in your Activity (the proper way) instead of the adapter.

Use same Recycler Adapter for inflating different activities

I have the following adapter
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder>{
List<String> list;
int id;
Context context;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(id,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.textView.setText(list.get(position));
holder.textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Handler handler=new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(context, BESyllabus.class);
context.startActivity(intent);
}
},500);
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView textView;
public CardView cardView;
public ViewHolder(View v){
super(v);
textView=(TextView)v.findViewById(R.id.text);
cardView=(CardView)v.findViewById(R.id.card_view);
}
}
public CardAdapter(List<String> list, int id,Context context){
this.list=list;
this.id=id;
this.context=context;
}
}
I use the same layout file which has a recyclerView which uses the above adapter,id is the resource id for layout file which i use as rows for recycler view`
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:alpha="0.87"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:textSize="35dp" />
What i want to do is inflate multiple activities using the same row structure using the same adapter. It works fine while displaying the rows but the same onClickListener is used in every activity relaunching the same activity every time i click. Is there a way to use the same adapter where i can assign listeners based on the activity.Or should i create new adapter for every activity? I am new to android development so any help will be appreciated.Thanks in advance.
Use the interface :
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder>{
private IOnItemClickListener mListener;
public CardAdapter(IOnItemClickListener mListener) {
this.mListener = mListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(id,parent,false);
return new ViewHolder(v, new CardAdapter.ViewHolder.IMyViewHolderClicks() {
public void onClick(View v, int position) {
mListener.onItemClick(v, position);
};
});
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView textView;
public CardView cardView;
public IMyViewHolderClicks mListener;
public ViewHolder(View v, IMyViewHolderClicks listener) {
super(itemView);
mListener = listener;
textView=(TextView)v.findViewById(R.id.text);
cardView=(CardView)v.findViewById(R.id.card_view);
}
#Override
public void onClick(View v) {
mListener.onClick(v, getPosition());
}
public interface IMyViewHolderClicks {
public void onClick(View v, int position);
}
}
}
public interface IOnItemClickListener {
public void onItemClick(View v, int position);
}
You should pass an OnClickListener to the CardAdapter (on its constructor maybe) and implement it on the activity working with this Adapter.
public class ActivityX extends Activity implements View.OnClickListener {
CardAdapter adapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
adapter = new CardAdapter(this)
}
public void onClick(View v) {
// Handle click here
String string = (String) v.getTag();
}
}
Your Adapter may then look like this:
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
View.OnClickListener onClickListener;
public CardAdapter(View.OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// Saving object from list at given position in View tag
holder.setTag(list.get(position));
holder.textView.setText(list.get(position));
holder.textView.setOnClickListener(onClickListener);
}
}
You can pass the listener as a constructor argument to the Adapter
In this answer there's an implementation of a onItemClickListener for a recycler view. You could move the code from your onClickListener to a diferent onItemClickListener for each diferent activity you need.
First of all, what is a reason to use handler delay in setOnClickListener? This code will lead to an NullPointerException in cases when context was destroyed before.
On the subject of the question you could pass onClickListener via constructor as in previous answers, pass only Class variable of target activity, make broadcast event. It depends on your needs. But the most appropriate in most cases i think is not make onClickListener inside adapter, setting onItemClickListener of recycler view instead (as #tinuviel answer). In this case pressed state of recycle view item will be animated automatically

Categories

Resources