I have a recycler view and I am implementing OnClicklistener inside it. Basically , I have an adapter class called actressadapter and a viewholder class MyViewHolder.I am implementing OnClickListener inside viewholder class to initiate another activity via intent method. My basic data is inside a class called actress which has three variables name,country(both String) and an Id(UUID). I am providing this data that is of actresses to my adapter.Next activity is just displaying the name of actress like abc ,def etc that it retrieves . The fault is that it shows name of only one actress after clicking. For instance if it shows abc ,then for each click it will show abc.Don't know why is this happening because as per code I am passing actressname as an extra .
public class actressadapter extends RecyclerView.Adapter <actressadapter.MyViewHolder> {
private List<Actress>al;
private Actress actress,mActress;
public static final String str="shivam.panwar.actressdetails.actressadapter.str";
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView naam, desh;
public MyViewHolder(View view) {
super(view);
view.setOnClickListener(this);
naam = (TextView) view.findViewById(R.id.name);
desh= (TextView) view.findViewById(R.id.country);
}
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(),"Clicked",Toast.LENGTH_SHORT).show();
Intent intent=new Intent(v.getContext(),Actressview.class);
intent.putExtra(str,actress.getName());
v.getContext().startActivity(intent);
}
public void bindactress(Actress mActress) {
naam.setText(mActress.getName());
desh.setText(mActress.getCountry());
}
}
public actressadapter(List<Actress> al) {
this.al = al;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.actress_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
actress =al.get(position);
holder.bindactress(actress);
}
#Override
public int getItemCount() {
return al.size();
}
}
If required any further assist about code please comment.
try this way hope it works...
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
actress =al.get(position);
holder.bindactress(actress);
holder.naam.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,holder.naam.getText().toString(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context,Actressview.class);
intent.putExtra(str,holder.naam.getText().toString());
context.startActivity(intent);
}
});
}
The best way to use the method getLayoutPosition() of adapter class to get the selected item(position).
You have to update your code for better result. Replace your existing code with that.
public class actressadapter extends RecyclerView.Adapter <actressadapter.MyViewHolder> {
private List<Actress>al;
private Actress actress,mActress;
private int itemPosition; // change
public static final String str="shivam.panwar.actressdetails.actressadapter.str";
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView naam, desh;
public MyViewHolder(View view) {
super(view);
view.setOnClickListener(this);
naam = (TextView) view.findViewById(R.id.name);
desh= (TextView) view.findViewById(R.id.country);
}
#Override
public void onClick(View v) {
itemPosition = getLayoutPosition(); // change
Toast.makeText(v.getContext(),"Clicked",Toast.LENGTH_SHORT).show();
Intent intent=new Intent(v.getContext(),Actressview.class);
intent.putExtra(str,al.get(itemPosition).getName()); // change
v.getContext().startActivity(intent);
}
public void bindactress(Actress mActress) {
naam.setText(mActress.getName());
desh.setText(mActress.getCountry());
}
}
public actressadapter(List<Actress> al) {
this.al = al;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.actress_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
actress =al.get(position);
holder.bindactress(actress);
}
#Override
public int getItemCount() {
return al.size();
}
}
Hope it will work..
your issue is that you made actress a variable of the Adapte, and it should be of the Holder.
To fix it:
Delete the line:
private Actress actress,mActress;
Change the onBindViewHolder method to:
holder.bindactress(al.get(position))
And make replace your holder class with that:
// holder HAVE TO be static. It's WRONG not doing it static
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView naam, desh;
Actress actress;
public MyViewHolder(View view) {
super(view);
view.setOnClickListener(this);
naam = (TextView) view.findViewById(R.id.name);
desh= (TextView) view.findViewById(R.id.country);
}
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(),"Clicked",Toast.LENGTH_SHORT).show();
Intent intent=new Intent(v.getContext(),Actressview.class);
intent.putExtra(str,actress.getName());
v.getContext().startActivity(intent);
}
public void bindactress(Actress mActress) {
this.actress = mActress;
naam.setText(mActress.getName());
desh.setText(mActress.getCountry());
}
}
Related
Sorry, i have a problem, i have created ad adapter for a recyclerView to click on one of my item but it doesn't work, it is very frustrating, do you have any ideas?
I have used it in a old application and it works properly but now i don't know why it doesn't work...
Here is my adapter:
public class TecniciAdapter extends RecyclerView.Adapter<TecniciAdapter.MyViewHolder> {
private Context mContext;
private List<Utenti> tecniciList;
private OnTecniciListner onTecniciListner;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView nome;
public TextView cognome;
public TextView stato;
public OnTecniciListner onTecniciListner;
public MyViewHolder(View view, OnTecniciListner onTecniciListner) {
super(view);
nome = view.findViewById(R.id.textNome);
cognome = view.findViewById(R.id.textCognome);
stato = view.findViewById(R.id.textCurrentState);
this.onTecniciListner = onTecniciListner;
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onTecniciListner.onTecniciClick(getAdapterPosition());
}
}
public TecniciAdapter(Context context, ArrayList<Utenti> list, OnTecniciListner onTecniciListner) {
this.mContext = context;
this.tecniciList = list;
this.onTecniciListner = onTecniciListner;
}
#NonNull
#Override
public TecniciAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext)
.inflate(R.layout.technician_item, viewGroup, false);
return new TecniciAdapter.MyViewHolder(view, onTecniciListner);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.nome.setText(tecniciList.get(i).getNome());
myViewHolder.cognome.setText(tecniciList.get(i).getCognome());
myViewHolder.stato.setText(tecniciList.get(i).getStato());
}
#Override
public int getItemCount() {
return tecniciList.size();
}
public interface OnTecniciListner{
void onTecniciClick(int position);
}
}
and this is the part in the fragment:
TecniciAdapter adapter = new TecniciAdapter(getActivity(), tecniciList, TecniciFragment.this);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(adapter);
I have also this in my fragment:
#Override
public void onTecniciClick(int position) {
Utenti tecnici = tecniciList.get(position);
Intent intent = new Intent(getActivity(), LoginActivity.class);
startActivity(intent);
}
You do not need to create an instance of OnTecniciListner in your ViewHolder class, the one in the TecniciAdapter should work just fine.
So your MyViewHolder class should look like this
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView nome;
public TextView cognome;
public TextView stato;
public MyViewHolder(View view) {
super(view);
nome = view.findViewById(R.id.textNome);
cognome = view.findViewById(R.id.textCognome);
stato = view.findViewById(R.id.textCurrentState);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onTecniciListner.onTecniciClick(getAdapterPosition());
}
}
in onBindViewHoldertry this :
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
i have a recyclerview and i want to when click on it receive the position and one String and sent to other activity and run it
i dont know where this code has problem.
Mainactivity
#Override
public void onItemClick(int i) {
datamodel clickedItem = postlist.get(i);
Intent detailIntent = new Intent(MainActivity.this, Main2Activity.class);
detailIntent.putExtra(EXTRA_URL, clickedItem.getmTitle());
startActivity(detailIntent);
}
Adapter codes:
public class rrecyclerviewadapter extends RecyclerView.Adapter<rrecyclerviewadapter.myholder> {
private OnItemClickListener mListener;
private Context context;
private List<datamodel>mylist;
public interface OnItemClickListener {
void onItemClick(int i);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
}
public rrecyclerviewadapter(Context context, List<datamodel>mylist){
this.context=context;
this.mylist=mylist;
}
#NonNull
#Override
public myholder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view= LayoutInflater.from(context).inflate(R.layout.each_item,viewGroup,false);
return new myholder(view);
}
#Override
public void onBindViewHolder(#NonNull myholder myholder, int i) {
datamodel datamodel=mylist.get(i);
myholder.eachitemtxt.setText(datamodel.getmTitle());
Picasso.with(context).load(datamodel.getMimageurl()).placeholder(R.drawable.pic3).error(R.drawable.pic4).into(myholder.eachitemimg);
}
#Override
public int getItemCount() {
return mylist.size();
}
public class myholder extends RecyclerView.ViewHolder {
private TextView eachitemtxt;
private ImageView eachitemimg;
public myholder(#NonNull final View itemView) {
super(itemView);
eachitemimg = (ImageView) itemView.findViewById(R.id.imageview_eachitem);
eachitemtxt = (TextView) itemView.findViewById(R.id.textview_eachitem);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "id:" + getAdapterPosition(),
Toast.LENGTH_SHORT).show();
int i=getAdapterPosition();
if (i != RecyclerView.NO_POSITION) {
mListener.onItemClick(i);
}}
});}}}
here there is full adapter code
on other activity i get intent.
in the adapter when testing Toast its completely works but on the mlistener and
setting id it does not work
found it.
just need to add
Adapter.setOnItemClickListener(Activitymain.this)
to your Mainactivity
i just changed your holder class in adapter try the below code
public class myholder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView eachitemtxt;
private ImageView eachitemimg;
public myholder(#NonNull final View itemView) {
super(itemView);
eachitemimg = (ImageView) itemView.findViewById(R.id.imageview_eachitem);
eachitemtxt = (TextView) itemView.findViewById(R.id.textview_eachitem);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int p = getAdapterPosition();
datamodel clickedItem = postlist.get(p);
Intent detailIntent = new Intent(context, Main2Activity.class);
detailIntent.putExtra(EXTRA_URL, clickedItem.getmTitle());
context.startActivity(detailIntent);
}
}
Everything works well and my onClick in my recyclerView is working in getting the positions of my items, but what my design calls for is to be able to click an item of the recyclerView and open up a new activity (as a popover or pop up). I can achieve this but my problems comes with the information I need to display on the popover. The information comes like this inside the activity (inside a Firebase value call)
attributeList.removeAll(attributeList);
for (DataSnapshot child : dataSnapshot.child("Attribute").getChildren()){
Attribute attribute = child.getValue(Attribute.class);
attribute_list newAttributeList = new attribute_list( attribute.Name + ": " + attribute.Value);
attributeList.add(newAttributeList);
}
attributeAdapter = new attribute_list_adapter(attributeList, getContext());
recyclerAttribute.setAdapter(attributeAdapter);
This works perfectly for displaying the information, but there's more then just a "value" and a "name" associated with the click.
Basically when I select an item, I need to get the position of the item clicked (which I have) and compare it to the position inside attributeList so I can call a Firebase call (or pass the data somehow) to the popover to display values from the "Attribute" class (such as Name, Value, Description, and another list (recyclerView).
My recyclerView:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
attribute_list listItem = listItems.get(position);
holder.txtTitle.setText(listItem.getTxtTitle());
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView txtTitle;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
txtTitle = (TextView) itemView.findViewById(R.id.txtTitle);
}
#Override
public void onClick(View v) {
}
}
}
This is example:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.onClickListener() {
#Override
public void onClick(View v) {
onItemClickListener.onItemClick(position);
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txtberita;
ImageView imgberita;
TextView txtnama;
public ViewHolder(View itemView) {
super(itemView);
txtnama = (TextView) itemView.findViewById(R.id.txtnama);
txtberita = (TextView) itemView.findViewById(R.id.txtberita);
imgberita = (ImageView) itemView.findViewById(R.id.imgberita);
}
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
OnItemClickListener onItemClickListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
}
your Activity. in Oncreate()
public class TestActivity extends AppCompatActivity implements attribute_list_adapter.OnItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
attribute_list_adapter adapter = new attribute_list_adapter(listItems, this);
adapter.setOnItemClickListener(this);
}
#Override
public void onItemClick(int position) {
// code here
}
}
Create an interface something like
public interface OnSingleItemClickListener{
void onSingleItemClick(int position);
}
Then implement it on your ViewHolder like this
public class ViewHolder extends RecyclerView.ViewHolder implements OnSingleItemClickListener {
public ViewHolder(View itemView) {
super(itemView);
}
#Override
void onSingleItemClick(int position){
if(listItems.get(position) == listItems.get(getAdapterPosition)){
// TODO do something here
}
}
now on your OnBindViewHolder inside your adapter you must do this.
holder.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
holder.onSingleItemClick(position);
}
}):
I have prepared a Database in my asset folder . I have one recyclerView for showing the title in the database . Now i want show DetailActivity with specificid . my means is show description of post . I think it can be done with intent , but i don't know how .
public class FehrestRecyclerAdapter extends RecyclerView.Adapter<FehrestRecyclerAdapter.ViewHolder> {
private Context ctx;
private List<Post> posts;
//constructor
public FehrestRecyclerAdapter(Context ctx, List<Post> posts) {
this.ctx = ctx;
this.posts= posts;
}
//ViewHodler Pattern
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView txtTitle;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
txtTitle= (TextView)itemView.findViewById(R.id.txtTitle);
}
#Override
public void onClick(View v) {
//Toast.makeText(v.getContext() , txtTitle.getText() , Toast.LENGTH_SHORT).show();
Intent intent = new Intent(itemView.getContext() , DetailActivity.class);
intent.putExtra("postId" , "id");
itemView.getContext().startActivity(intent);
}
}
//OncreateViewHolder
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_row , parent , false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
//OnBindViewHolder
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Post current = Post.get(position);
holder.txtTitle.setText(current.getTitle());
}
//getItemCount method
#Override
public int getItemCount() {
return posts.size();
}
}
i have a 3 columns in my database
1.id 2.title 3.desc
and 3 methods in my Post model Class :
getId() 2.getTitle() 3.getDesc()
as you can see i can send intent to DetailActivity . But i don't know how can i achieve to sending specific id to DetailActivity. thanks
Make one Variable id in ViewHolder and assign that in onBindViewHolder() , I updated the code according to that.
public class FehrestRecyclerAdapter extends RecyclerView.Adapter<FehrestRecyclerAdapter.ViewHolder> {
private Context ctx;
private List<Post> posts;
//constructor
public FehrestRecyclerAdapter(Context ctx, List<Post> posts) {
this.ctx = ctx;
this.posts= posts;
}
//ViewHodler Pattern
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView txtTitle;
private int id;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
txtTitle= (TextView)itemView.findViewById(R.id.txtTitle);
}
#Override
public void onClick(View v) {
//Toast.makeText(v.getContext() , txtTitle.getText() , Toast.LENGTH_SHORT).show();
Intent intent = new Intent(itemView.getContext() , DetailActivity.class);
// here pass id through intent
intent.putExtra("postId" , id);
itemView.getContext().startActivity(intent);
}
}
//OncreateViewHolder
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_row , parent , false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
//OnBindViewHolder
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Post current = Post.get(position);
holder.txtTitle.setText(current.getTitle());
// add this line
holder.id = Post.get(postion).getId();
}
//getItemCount method
#Override
public int getItemCount() {
return posts.size();
}
}
How can i achieve to sending specific id to DetailActivity
Use setTag method of holder.txtTitle TextView for storing id with TextView and call getTag inside onClick of View Click like:
1. In onBindViewHolder save current using setTag:
holder.txtTitle.setTag(current);
holder.txtTitle.setText(current.getTitle());
2. In onClick of View use getTag as:
#Override
public void onClick(View v) {
txtTitle= (TextView)v.findViewById(R.id.txtTitle);
Post current=(Post)txtTitle.getTag();
intent.putExtra("postId" , current.getId());
intent.putExtra("postTitle" , current.getTitle());
....
}
When a button is clicked, I'm trying to delete the row. At the very bottom, I call the delete method that I made. However it gives me an error (in the question). I tried making the delete method static, tried everything that android suggested
public class myAdapter extends RecyclerView.Adapter<myAdapter.ViewHolder> {
private List<numbers> mNumbers;
public myAdapter (List<numbers> numbers) {
mNumbers = numbers;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_slot, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bindNumbers(mNumbers.get(position));
}
#Override
public int getItemCount() {
return mNumbers.size();
}
public void delete(int position) {
mNumbers.remove(position);
notifyItemRemoved(position);
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView numberText;
EditText checklistText;
Button deleteButton;
CheckBox checkDisBox;
public ViewHolder(View itemView) {
super(itemView);
numberText = (TextView) itemView.findViewById(R.id.number);
checklistText = (EditText) itemView.findViewById(R.id.editText);
deleteButton = (Button) itemView.findViewById(R.id.deleteButton);
checkDisBox = (CheckBox) itemView.findViewById(R.id.checkBox);
deleteButton.setOnClickListener(this);
}
public void bindNumbers(numbers numbers) {
numberText.setText(numbers.getInt() + "");
}
#Override
public void onClick(View v) {
delete(getAdapterPosition());
}
}
}
EDITED PROBLEM BELOW
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bindNumbers(mNumbers.get(position));
holder.deleteButton.setOnClickListener(this);
}
public void delete(int position) {
mNumbers.remove(position);
notifyItemRemoved(position);
}
#Override
public void onClick(View v) {
delete(getAdapterPosition());
}
Edit
I just went and implemented this myself, and this is what worked for me.
Create an interface for deleting items
public interface DeleteItem {
void delete(int position);
}
Make your adapter implement this interface
public class myAdapter
extends RecyclerView.Adapter<myAdapter.ViewHolder>
implements DeleteItem {
#Override
public void delete(int position) {
mNumbers.remove(position);
notifyItemRemoved(position);
}
}
Set your viewholder to take a reference to the interface
DeleteItem mDeleteItem;
public ViewHolder(View itemView, DeleteItem deleteItem) {
super(itemView);
mDeleteItem = deleteItem;
...
}
Modify your view holders on click handler
#Override
public void onClick(View v) {
mDeleteItem.delete(getAdapterPosition());
}
Finally when creating your view holder pass it the reference
ViewHolder vh = new ViewHolder(v, this);
Original Answer
A ViewHolder is to save your application from having to find the views inside of list items. It should only contain the myview = itemView.findViewById() type calls and nothing else.
The bindViewHolder() method should contain all the code that uses those views you found in the view holder.
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.bindNumbers(mNumbers.get(position));
// add listener here
holder.deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
delete(position);
}
}
}
Code hasnt really changed from my question but removing the static keyword really got rid of a lot of my struggles
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView numberText;
EditText checklistText;
Button deleteButton;
CheckBox checkDisBox;
public ViewHolder(View itemView) {
super(itemView);
numberText = (TextView) itemView.findViewById(R.id.number);
checklistText = (EditText) itemView.findViewById(R.id.editText);
deleteButton = (Button) itemView.findViewById(R.id.deleteButton);
checkDisBox = (CheckBox) itemView.findViewById(R.id.checkBox);
deleteButton.setOnClickListener(this);
}
public void bindNumbers(numbers numbers) {
numberText.setText(numbers.getInt() + "");
}
#Override
public void onClick(View v) {
delete(getAdapterPosition());
}
}
my delete method
public void delete(int position) {
mNumbers.remove(position);
notifyItemRemoved(position);
}