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
Related
I used android RecyclerView.Adapter. i can not manage my onClickListener.When I do click on item worked and this ithem and another item
When I set my itemView
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
view.setVisibility(View.GONE);
}
});
and when do click 'GONE' works to two items.
see in photo
this my adapter.
public class WordAdapter extends RecyclerView.Adapter<WordAdapter.ViewHolder> {
private List<LessonListActivity.Words> words;
public WordAdapter(List<LessonListActivity.Words> words) {
this.words = words;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem = layoutInflater.inflate(R.layout.adapter_content, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final LessonListActivity.Words myListData = words.get(position);
holder.textView.setText(words.get(position).getEN());
}
#Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
#Override
public int getItemCount() {
return words.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
this.textView = (TextView) itemView.findViewById(R.id.word);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.relative_layout);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
view.setVisibility(View.GONE);
}
});
}
}
}
what can i do to make them work only if we click them?
You can use one list to save all selected indexes and use it in onBindViewHolder to manage visibility of views.
Add index to be removed in list by clicking on view.
public class WordAdapter extends RecyclerView.Adapter<WordAdapter.ViewHolder> {
private List<LessonListActivity.Words> words;
ArrayList<Integer> listSelected = new ArrayList<>();
public WordAdapter(List<Words> words) {
this.words = words;
}
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem = layoutInflater.inflate(R.layout.adapter_content, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final LessonListActivity.Words myListData = words.get(position);
holder.textView.setText(words.get(position).getEN());
if (listSelected.contains(position)) {
//Here view will be invisible it will show white space. you can set height 0 to remove white space.
holder.itemView.setVisibility(View.GONE);
} else holder.itemView.setVisibility(View.VISIBLE);
}
#Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
#Override
public int getItemCount() {
return words.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
this.textView = (TextView) itemView.findViewById(R.id.word);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.relative_layout);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!listSelected.contains(getLayoutPosition())) {
listSelected.add(getLayoutPosition());
}
notifyItemChanged(getLayoutPosition());
}
});
}
}
}
I am using RecyclerView and it has two TextViews; one for a question and one for an answer. Following is the view for reference. By default, I set the answer TextView to invisible to the user. Now if the user clicks on button answer will be visible. So far it works fine, now what I want is if user open answer for question 1 answer will be visible, now if the user clicks second listitem button then first answer TextView should be hidden. I want only one answer to be visible at a time.
Question 1 (Button)
Answer
Question 2 (Button)
Answer
Question 3 (Button)
Answer
Question 4 (Button)
Answer
public class BuyerFaqsAdapter extends RecyclerView.Adapter<BuyerFaqsAdapter.MyViewHolder> {
private ArrayList<BuyerMemberShipFAQParent> brandList;
private Context context;
private int counter;
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tvans,tvfaq;
public ImageView ivImage;
MyViewHolder(View view) {
super(view);
tvfaq = (TextView) view.findViewById(R.id.row_layout_faqtv);
tvans = (TextView) view.findViewById(R.id.row_layout_answertv);
ivImage = (ImageView) view.findViewById(R.id.row_layout_ivarrow);
}
}
public BuyerFaqsAdapter(final Context context, final ArrayList<BuyerMemberShipFAQParent> brandList) {
this.brandList = brandList;
this.context = context;
}
#Override
public BuyerFaqsAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_layout_faq_expand_parent, parent, false);
return new BuyerFaqsAdapter.MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final BuyerFaqsAdapter.MyViewHolder holder, final int position) {
holder.tvfaq.setText(brandList.get(position).getFAQParentText());
holder.tvans.setVisibility(View.GONE);
holder.tvans.setText(brandList.get(position).getFAQAnswerText());
holder.itemView.setId(position);
counter = 1;
holder.ivImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (counter == 1) {
holder.tvans.setVisibility(View.VISIBLE);
holder.ivImage.setImageResource(R.drawable.ic_arrow_faq_up);
counter = 2;
}
else {
holder.tvans.setVisibility(View.GONE);
holder.ivImage.setImageResource(R.drawable.ic_arrow_faq);
counter = 1;
}
}
});
}
#Override
public int getItemCount() {
return brandList.size();
}
I didn't tested it because I don't have your layout files but you should do something like this:
public class BuyerFaqsAdapter extends RecyclerView.Adapter<BuyerFaqsAdapter.MyViewHolder> {
private ArrayList<BuyerMemberShipFAQParent> brandList;
private Context context;
private MyViewHolder lastClickedHolder;
public BuyerFaqsAdapter(final Context context, final ArrayList<BuyerMemberShipFAQParent> brandList) {
this.brandList = brandList;
this.context = context;
}
#Override
public BuyerFaqsAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_layout_faq_expand_parent, parent, false);
return new BuyerFaqsAdapter.MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final BuyerFaqsAdapter.MyViewHolder holder, final int position) {
holder.tvfaq.setText(brandList.get(position).getFAQParentText());
holder.tvans.setVisibility(View.GONE);
holder.tvans.setText(brandList.get(position).getFAQAnswerText());
holder.itemView.setId(position);
holder.ivImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (lastClickedHolder != null) {
collapse(lastClickedHolder);
}
expand(holder);
lastClickedHolder = holder;
}
});
}
#Override
public int getItemCount() {
return brandList.size();
}
private void collapse(BuyerFaqsAdapter.MyViewHolder holder) {
holder.tvans.setVisibility(View.VISIBLE);
holder.ivImage.setImageResource(R.drawable.ic_arrow_faq_up);
}
private void expand(BuyerFaqsAdapter.MyViewHolder holder) {
holder.tvans.setVisibility(View.GONE);
holder.ivImage.setImageResource(R.drawable.ic_arrow_faq);
}
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tvans, tvfaq;
public ImageView ivImage;
MyViewHolder(View view) {
super(view);
tvfaq = (TextView) view.findViewById(R.id.row_layout_faqtv);
tvans = (TextView) view.findViewById(R.id.row_layout_answertv);
ivImage = (ImageView) view.findViewById(R.id.row_layout_ivarrow);
}
}
}
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);
}
If someone can help me. I've a RecyclerView with items but when i try to select ONE item, i can select many items. I think that the problem is in the onClick callback but i don't know exactly. This is the adapter code:
public class HorizontalRecyclerViewAdapter extends RecyclerView
.Adapter<HorizontalRecyclerViewAdapter
.DataObjectHolder> {
private ArrayList<HorizontalData> mDataset;
private static MyClickListener myClickListener;
private SparseBooleanArray selectedItem = new SparseBooleanArray();
public class DataObjectHolder extends RecyclerView.ViewHolder
implements View
.OnClickListener {
TextView mLabel;
TextView mDateTime;
LinearLayout linearLayout;
public DataObjectHolder(View itemView) {
super(itemView);
mLabel = (TextView) itemView.findViewById(R.id.item_list_view_text_view);
mDateTime = (TextView) itemView.findViewById(R.id.item_list_view_text_view_two);
linearLayout = (LinearLayout) itemView.findViewById(R.id.myBackground);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (selectedItem.get(getAdapterPosition(), false)) {
selectedItem.delete(getAdapterPosition());
v.setSelected(false);
} else {
selectedItem.put(getAdapterPosition(), true);
v.setSelected(true);
}
myClickListener.onItemClick(getAdapterPosition(), v);
}
}
public void setOnItemClickListener(MyClickListener myClickListener) {
this.myClickListener = myClickListener;
}
public HorizontalRecyclerViewAdapter(ArrayList<HorizontalData> myDataset) {
mDataset = myDataset;
}
#Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.date_item, parent, false);
DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
return dataObjectHolder;
}
#Override
public void onBindViewHolder(DataObjectHolder holder, int position) {
holder.linearLayout.setSelected(selectedItem.get(position, false));
holder.mLabel.setText(mDataset.get(position).getmTitle());
holder.mDateTime.setText(mDataset.get(position).getmSubTitle());
}
#Override
public int getItemCount() {
return mDataset.size();
}
public interface MyClickListener {
void onItemClick(int position, View v);
}
}
Thanks!
First of all you don't need SparseBooleanArray, because you want only one item to be selected. It'd be enough to have int selectedItemPos with would represent currently selected item position.
Here's a simple adapter that I've just created and it's working, with comments explaining what's happening:
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {
private ArrayList<String> items;
//field mentioned before
private int selectedItemPos = -1;
//I create some items to see if my adapter is working.
public TestAdapter() {
this.items = new ArrayList<>();
for (int i=0; i<20; i++) {
items.add("Test" + i);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false));
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
String item = items.get(position);
holder.mName.setText(item);
//This line sets selection state to true if current position is the same as selected one, and false otherwise.
holder.itemView.setSelected(selectedItemPos == position);
}
#Override
public int getItemCount() {
return items.size();
}
//helper method
protected void setSelectedItem(int position) {
int oldSelected = selectedItemPos;
selectedItemPos = position;
// update view of unselected item
notifyItemChanged(oldSelected);
//update view of just selected item
notifyItemChanged(selectedItemPos);
}
protected class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView mName;
public ViewHolder(View view) {
super(view);
mName = (TextView) view.findViewById(R.id.taskListItem_name);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
//if the clicked item is already selected,
// we will just unselect it and no new item will be selected
//(new one is -1, which is none)
int newSelectedItem = getAdapterPosition()==selectedItemPos?-1:getAdapterPosition();
//apply changes on adapter
setSelectedItem(newSelectedItem);
}
}
}
You should be able to easily merge this code with yours.
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);
}
});
}