recyclerview highlight just one item - android

i have recycler view and i highlight the item when i click in it , the problem is i can highlight many item , i wont just one item , when i click into item is highlight and when i click another item is highlight too
this is MyAdapter
public class ScreenRecyclerAdapter extends RecyclerView.Adapter<ScreenRecyclerAdapter.ViewHolder> {
Context context;
int image_list[];
ImageView image_view_screen_item;
public ScreenRecyclerAdapter(int[] image_list, Context context){
super();
this.image_list = image_list;
this.context = context;}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.screen_items, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Picasso.with(context).load(image_list[position]).into(holder.image_view_screen_item);
holder.list_row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
#Override
public int getItemCount() {
return image_list.length;
}
class ViewHolder extends RecyclerView.ViewHolder{
ImageView image_view_screen_item , back;
RelativeLayout list_row;
public ViewHolder(View itemView) {
super(itemView);
image_view_screen_item = (ImageView) itemView.findViewById(R.id.plantImageView);
list_row = (RelativeLayout) itemView.findViewById(R.id.list_row);
list_row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
list_row.setBackgroundColor(Color.parseColor("#d5d5d5"));
Intent i = new Intent(context, ImagePager.class);
context.startActivity(i);
}
});
}}}

First define a list of RelativeLayouts for your adapter which contains every rows:
List<RelativeLayout> items;
Then in your onBindViewHolder method, add:
items.add(holder.list_row);
Now add a method to your adapter like this:
private void makeAllWhite() {
for(RelativeLayout item : items) {
item.setBackgroundColor(Color.parseColor("#ffffff"));
}
}
Finally before this line:
list_row.setBackgroundColor(Color.parseColor("#d5d5d5"));
call:
makeAllWhite();
Your final code should be like this:
public class ScreenRecyclerAdapter extends RecyclerView.Adapter<ScreenRecyclerAdapter.ViewHolder> {
Context context;
int image_list[];
ImageView image_view_screen_item;
List<RelativeLayout> items;
public ScreenRecyclerAdapter(int[] image_list, Context context){
super();
this.image_list = image_list;
this.context = context;
this.items = new ArrayList<>();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.screen_items, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
items.add(holder.list_row);
Picasso.with(context).load(image_list[position]).into(holder.image_view_screen_item);
}
#Override
public int getItemCount() {
return image_list.length;
}
class ViewHolder extends RecyclerView.ViewHolder{
ImageView image_view_screen_item , back;
RelativeLayout list_row;
public ViewHolder(View itemView) {
super(itemView);
image_view_screen_item = (ImageView) itemView.findViewById(R.id.plantImageView);
list_row = (RelativeLayout) itemView.findViewById(R.id.list_row);
list_row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
makeAllWhite();
list_row.setBackgroundColor(Color.parseColor("#d5d5d5"));
Intent i = new Intent(context, ImagePager.class);
context.startActivity(i);
}
});
}
}
private void makeAllWhite() {
for(RelativeLayout item : items) {
item.setBackgroundColor(Color.parseColor("#ffffff")));
}
}
}

I have done the same thing here. There are multiple solutions to it but what I found most convenient is storing a copy of the view (or viewholder, both work) and in every onClick event check if the view (or viewholder) is same, if not then change the background of the previously selected view and set the new background for the selected item else use return ;

In your adapter, you're setting the OnClickListener for the ViewHolder, which is basically representing every item. The binding (of data, design, events, etc.) is happening in onBindViewHolder according to the position in the dataset. So just move your event implementation from the constructor of ViewHolder to onBindViewHolder.
It may be irrelevant because it seems that your dataset isn't modified by the event, but if it does, don't forget to call notifyDataSetChanged() after modification.

Related

(android) How to select singleItem in Recyclerview?

Hello.
I want to implement single item selection function in RecyclerView
RecyclerView's item is made up of TextView only.
When i clicked items, i want to change TextView's background color
I want to click only single item.
But items are clicked only multiple
When I click the first item and then the second item, the background color of the first item should be changed.
This is i wanted.
However i can't change the Text of the previous item in 'Adapter'.
I don't know how to get previous selected View.
How should i do?
Adapter.java
public class RoutineListAdapter extends RecyclerView.Adapter<RoutineListAdapter.ViewHolder> {
// ArrayList<RoutineListModel> items;
List<String> items = new ArrayList<>();
Context context;
public void addItems(List<String> items) {
this.items = items;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View itemView = inflater.inflate(R.layout.routine_list_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.setItem(items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView routine;
boolean isSelected;
public ViewHolder(#NonNull View itemView) {
super(itemView);
routine = itemView.findViewById(R.id.routine_list);
routine.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isSelected == false) {
routine.setBackgroundColor(context.getResources().getColor(R.color.light_green_dark));
isSelected = true;
}
else {
routine.setBackgroundColor(context.getResources().getColor(R.color.white));
isSelected = false;
}
}
});
}
private void setItem(String item) {
routine.setText(item);
}
}
}
ViewHolder's multiple instances are being created, so each instance has its own isSelected property and its value.
But what you need a singe common variable for all viewholder instance to refere it, hence the selectedPosition in the outer class, so it is only one, and when you click you set the current adapter position value to and with that you must notify the adapter, which will trigger to call the onBindViewHolder for all items and in the setItem() you can put up what you want to set background of views on basis of whatever conditions.
public class RoutineListAdapter extends RecyclerView.Adapter<RoutineListAdapter.ViewHolder> {
// ArrayList<RoutineListModel> items;
List<String> items = new ArrayList<>();
Context context;
int selectedPosition=-1;
//nothing selected initially
public void addItems(List<String> items) {
this.items = items;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View itemView = inflater.inflate(R.layout.routine_list_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.setItem(items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView routine;
public ViewHolder(#NonNull View itemView) {
super(itemView);
routine = itemView.findViewById(R.id.routine_list);
routine.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedPosition=getAdapterPosition();
notifyDataSetChanged();
}
});
}
private void setItem(String item) {
if(selectedPosition== getAdapterPosition()) {
routine.setBackgroundColor(context.getResources().getColor(R.color.light_green_dark));
}
else {
routine.setBackgroundColor(context.getResources().getColor(R.color.white));
}
routine.setText(item);
}
}

Display tick mark image when click on the name field in the RecyclerView?

I'm displaying the list of items in a RecyclerView. If I click on the item name I have to make the tick mark image visible. If i click on the name the image is visible but while I am scrolling the image position is changing continuously. Please can anyone help me to resolve this issue?
Here is my code for RecyclerViewAdapter
public class Category_adapter extends RecyclerView.Adapter<Category_adapter.MyViewHolder> {
Activity context;
boolean sample = false;
ArrayList data = new ArrayList<>();
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView txt_name;
ImageView img_select;
public MyViewHolder(View itemView) {
super(itemView);
txt_name = (TextView)itemView.findViewById(R.id.txt_category_new);
img_select = (ImageView) itemView.findViewById(R.id.img_select);
img_select.setVisibility(View.GONE);
txt_name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
img_select.setVisibility(View.VISIBLE);
Log.e("name", "Holder Name" + txt_name.getText().toString());
}
});
}
}
public Category_adapter(Activity con, ArrayList data) {
this.data = data;
this.context = con;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.category_adapter, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
holder.txt_name.setText(data.get(listPosition).toString());
}
#Override
public int getItemCount() {
return data.size() ;
}
}
ArrayList<Boolean> clicked = new ArrayList<>();
and save the value clicked.
and onBindView holder put something like this:
if(clicked.get(position)){
view.setvisiblity(View.VISIBLE);
}else{
view.setvisiblity(View.GONE);
}

textview background not changing after clicking

I wrote a code about changing the TextView background after clicking the text, however the background color did not change but the other TextView background color change. I understand recyclerview is to reuse the view, so i set notifyItemchanged() to avoid it to reset the view.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private List<String> innertext;
private Context mContext;
public MyAdapter(List<String> items,Context context){
this.innertext = items;
this.mContext = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.background_color, parent, false);
MyViewHolder holder = new MyViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
String s = innertext.get(position);
holder.t1.setText(s);
}
#Override
public int getItemCount() {
return innertext.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView t1;
public MyViewHolder(View itemView) {
super(itemView);
t1 = (TextView)itemView.findViewById(R.id.t1);
t1.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int pos = getAdapterPosition();
t1.setBackgroundColor(Color.parseColor("#455A64"));
notifyItemChanged(pos);
}
}
}
if you need more code from me please let me know.
This is not a tried code but it will explain the logic to you:-
public class MyAdapter extends RecyclerView.Adapter {
private List<String> innertext;
private Context mContext;
private boolean[] checked={false};
public MyAdapter(List<String> items, Context context) {
this.innertext = items;
this.mContext = context;
checked = new boolean[items.size()];
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.background_color, parent, false);
MyViewHolder holder = new MyViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
String s = innertext.get(position);
((MyViewHolder)holder).t1.setText(s);
if(checked[position]){
((MyViewHolder)holder).t1.setBackgroundColor(Color.parseColor("#455A64"));
}
}
#Override
public int getItemCount() {
return innertext.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView t1;
public MyViewHolder(View itemView) {
super(itemView);
t1 = (TextView) itemView.findViewById(R.id.t1);
t1.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int pos = getAdapterPosition();
checked[pos] = true;
notifyItemChanged(pos);
}
}
}
basically you have to store the position which has been clicked in a boolean array and then set color in onbindview by checking if it has been clicked, as recyclerview doesnt work the way u think, it recycle Views
Try this:
t1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
t1.setBackgroundColor(Color.parseColor("#455A64"));
}
});
Hope it helps.
This may help you
copy & paste below code in method onBindViewHolder
holder.t1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
t1.setBackgroundColor(ContextCompat.getColor(mContext, Color.parseColor("#455A64")););
}
});
+1 to #ankitagrawal. I think that's the correct solution!
This is my answer.
- The same logic but different approach. Hope i did this right because i'm not using AS or eclipse. I just modified #ankitagrawal's answer. Thanks :)
http://pastebin.com/C7fqhhUa

RecyclerView set Click Listener, nothing happen after I click

I am trying to set Click Listener to my RecyclerView, but when I click it, nothing happens.
Below is my Adapter code. What I did is attach click events within the ViewHolder within my adapter,
I could't find what wrong here:
public class HomeSetsViewAdapter extends RecyclerView.Adapter<HomeSetsViewAdapter.ViewHolder> {
private Context context;
// Pass in the context and posts array into the constructor
public HomeSetsViewAdapter(Context context, ArrayList<Post> posts) {
this.posts = posts;
this.context = context;
}
// Store a member variable for the users
private ArrayList<Post> posts;
#Override
public HomeSetsViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
// to inflate the item layout and create the holder
// Inflate the custom layout
View itemView = LayoutInflater.from(context).inflate(R.layout.layout_viewholderset, parent, false);
return new HomeSetsViewAdapter.ViewHolder(context, itemView);
}
// to set the view attributes based on the data
// Get the data model based on position
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Post post = posts.get(position);
if (position % 2 == 0) {
holder.getmainPic().setImageResource(R.drawable.pic3);
} else
holder.getmainPic().setImageResource(R.drawable.pic4);
// Set item views based on the data model
}
#Override
public int getItemCount() {
return posts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// Your holder should contain a member variable
// for any view that will be set as you render a row
private ImageView main_pic;
private Context context;
// constructor
public ViewHolder(View itemView) {
super(itemView);
this.main_pic = (ImageView) itemView.findViewById(R.id.main_pic);
// Attach a click listener to the entire row view
itemView.setOnClickListener(this);
}
// constructor
public ViewHolder(Context context, View itemView) {
super(itemView);
this.main_pic = (ImageView) itemView.findViewById(R.id.main_pic);
this.context = context;
// Attach a click listener to the entire row view
itemView.setOnClickListener(this);
}
public ImageView getmainPic() {
return main_pic;
}
public void setmainPic(ImageView main_pic) {
this.main_pic = main_pic;
}
// Handles the row being being clicked
#Override
public void onClick(View v) {
Intent intent = new Intent(context, HomePostPagerActivity.class);
context.startActivity(intent);
}
}
}
I don't see your item layout file (layout_viewholderset.xml), but you should set the root view of it focusable and clickable, like this:
android:focusable="true"
android:clickable="true"

Changing the Position of clicked item in RecyclerView on scroll

On click of button when I'm scrolling the view, it changes the
position of that clicked button. On every scroll it's showing different
position.
public class ProductAdapter extends
RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
Context ctx;
ArrayList<ProductDetail> productList;
public ProductAdapter(Context ctx, ArrayList<ProductDetail> productList) {
this.ctx = ctx;
this.productList = productList;
}
#Override
public int getItemCount() {
return productList.size();
}
#Override
public void onBindViewHolder(final ProductViewHolder vHolder, int pos) {
vHolder.txt_prod_name.setText(productList.get(pos).getProduct_desc());
vHolder.btn_add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
vHolder.lyt_prod_qty.setVisibility(View.VISIBLE);
vHolder.btn_add.setVisibility(View.GONE);
}
});
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int arg1) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.activity_recycler_search_item, null);
ProductViewHolder viewHolder = new ProductViewHolder(view);
return viewHolder;
}
public class ProductViewHolder extends RecyclerView.ViewHolder {
TextView txt_prod_name;
TextView txt_delivery_type;
TextView txt_prod_mrp;
Spinner spn_prod_qty;
LinearLayout list_lyt, lyt_prod_qty;
Button btn_add;
public ProductViewHolder(View itemView) {
super(itemView);
txt_prod_name = (TextView) itemView
.findViewById(R.id.txt_prod_name);
txt_delivery_type = (TextView) itemView
.findViewById(R.id.txt_delivery_type);
txt_prod_mrp = (TextView) itemView.findViewById(R.id.txt_prod_mrp);
btn_add = (Button) itemView.findViewById(R.id.btn_add);
lyt_prod_qty = (LinearLayout) itemView
.findViewById(R.id.lyt_prod_qty);
}
}
}
On click of Button when I'mm scrolling the view, it changes the position of that clicked button. On every scroll it's showing different
position. Where should I out my click logic or should refresh the adapter every time?
In your ProductDetail modal class add a member boolean isButtonClicked; and add its getter and setter as well. Then make following changes in your onBindViewHolder method:
#Override
public void onBindViewHolder(final ProductViewHolder vHolder, int pos) {
final ProductDetail productDetail = productList.get(pos);
vHolder.txt_prod_name.setText(productDetail.getProduct_desc());
if(productDetail.isButtonClicked()){
vHolder.lyt_prod_qty.setVisibility(View.VISIBLE);
vHolder.btn_add.setVisibility(View.GONE);
} else {
vHolder.lyt_prod_qty.setVisibility(View.GONE);
vHolder.btn_add.setVisibility(View.VISIBLE);
}
vHolder.btn_add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
vHolder.lyt_prod_qty.setVisibility(View.VISIBLE);
vHolder.btn_add.setVisibility(View.GONE);
productDetail.setIsButtonClicked(true);
}
});
}

Categories

Resources