Reputation: 468
I have created a RecyclerView which inflates three text views and an image view from a xml file. I would like to know how can I change (update) the values of the view that has been clicked?
So far I have set up the OnItemTouchListener which works fine, I can use it to detect which view has been clicked from within it. I don't know where to go from here, how do I change the data in the clicked view without inflating the whole RecyclerView again? I have used this tutorial to start with RecyclerView.
I have tried searching stackoverflow and gave google a shot but found nothing relevent.
EDIT:
I am inflating the RecyclerView with ItemData:
ItemData itemsData[] = {
new ItemData(getString(R.string.upgrade1_title),R.drawable.upgrade1image,getString(R.string.upgrade1_description),getString(R.string.upgrade1_price)),
new ItemData(getString(R.string.upgrade2_title),R.drawable.upgrade2image,getString(R.string.upgrade2_description),getString(R.string.upgrade2_price)),
new ItemData(getString(R.string.upgrade3_title),R.drawable.upgrade3image,getString(R.string.upgrade3_description),getString(R.string.upgrade3_price)),
ItemData class setters & getters
public class ItemData {
private String title;
private String description;
private String price;
private int imageUrl;
public ItemData(String title,int imageUrl, String desciption, String price){
this.title = title;
this.description = desciption;
this.price = price;
this.imageUrl = imageUrl;
}
public CharSequence getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
// The rest were removed to save space in the question
And finally the adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ItemData[] itemsData;
public MyAdapter(ItemData[] itemsData) {
this.itemsData = itemsData;
}
// Create new views (invoked by the layout manager)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_row, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
// - get data from your itemsData at this position
// - replace the contents of the view with that itemsData
viewHolder.txtViewTitle.setText(itemsData[position].getTitle());
viewHolder.txtViewDescription.setText(itemsData[position].getDesciption());
viewHolder.txtViewPrice.setText(itemsData[position].getPrice());
viewHolder.imgViewIcon.setImageResource(itemsData[position].getImageUrl());
}
// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtViewTitle, txtViewDescription, txtViewPrice;
public ImageView imgViewIcon;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.textTitle);
txtViewDescription = (TextView) itemLayoutView.findViewById(R.id.textDescription);
txtViewPrice = (TextView) itemLayoutView.findViewById(R.id.textPrice);
imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.imageIcon);
}
}
public void updateListValues (int position, int newVal) {
}
// Return the size of your itemsData (invoked by the layout manager)
@Override
public int getItemCount() {
return itemsData.length;
}
}
Upvotes: 0
Views: 9040
Reputation: 8826
Either do something in onclick or use an interface to get the data and do your stuff. After that you need to call notifyDataSetChanged()
static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public ViewHolder(View view) {
// your code
view.setOnClickListener(this)
}
@Override
public void onClick(View v) {
int position = getPosition();
// your changes
notifyDataSetChanged();
}
}
Upvotes: 1
Reputation: 1599
I suggest you add a boolean field to the ItemData class, called it selected. Then on bindViewHolder, you check if ItemData in that position was selected or not, if it was change the properties of your view to indicate selection, otherwise reset it to the default properties. You can toggle the selected value on your onItemTouched listener, and don't forget to call notifyDataSetChanged() preferably with position.
Something like this:
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
// - get data from your itemsData at this position
// - replace the contents of the view with that itemsData
viewHolder.txtViewTitle.setText(itemsData[position].getTitle());
viewHolder.txtViewDescription.setText(itemsData[position].getDesciption());
viewHolder.txtViewPrice.setText(itemsData[position].getPrice());
viewHolder.imgViewIcon.setImageResource(itemsData[position].getImageUrl());
if(itemsData[position].isSelected()) {
//Do something about it.
} else {
//Else return to default state, this is important because views will be recycled.
}
}
Upvotes: 0
Reputation: 2732
On click change the appropriate item in the adapter and call notifyItemChanged(position)
. The adapter will then notify the RecyclerView of the change and it will rende that item again, but only that item so it's efficient.
Upvotes: 2