Highlighted Items in reyclerview lose their state when scolling - android-recyclerview

I am trying to highlight clicked items in recylerview but as soon as when you scroll the highlighted items do not stay highlighted anymore. I do not know how to keep their state when scrolling. The implementation in the adapter class and given below:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>{
boolean isEnable = false;
List<ItemFiles> selectList = new ArrayList<>();
public MyAdapter.MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout._main,parent,false);
return new MyViewHolder(view);
public void onBindViewHolder(#NonNull MyAdapter.MyViewHolder holder, int
position) {
holder.item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isEnabled) {
ClickItem(holder);
}
}
private void ClickItem(MyHolder holder) {
ItemFiles s = files.get(holder.getAdapterPosition());
if (holder.highlightItem.getVisibility() == View.GONE){
holder.highlightItem.setVisibility(View.VISIBLE);
holder.highlightItem.setBackgroundColor(Color.LTGRAY);
selectList.add(s);
// this is what I tried to keep the highlighted state but no result
selectList.get(holder.getAdapterPosition()).setSelected(true);
} else {
holder.highlightItem.setVisibility(View.GONE);
holder.highlightItem.setBackgroundColor(Color.TRANSPARENT);
selectList.remove(s);
selectList.get(holder.getAdapterPosition()).setSelected(false);
}
}
}

Related

highlight items in recyclerview android

I am trying to select items in recylerview. When I click an item, a checkbox appears on that item and it is highlighted. But the problem is that when I scroll, the item which is highlighted goes to its original color but the checkbox image remains as it should. Why the highlighted color is gone but the image remains after scrolling, I want the items to keep their state after scrolling.
public static List<Model> item = new ArrayList<Model>()
#Override
public void onBindViewHolder(#NonNull MyAdapter.MyViewHolder holder, int
position) {
holder.bind(item.get(position));
//
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.check);
public void bind(Model model) {
if (model.isChecked()){
imageView.setVisibility(View.VISIBLE);
itemView.setBackgroundColor(Color.GRAY);
model.setChecked(true);
} else {
imageView.setVisibility(View.GONE);
itemView.setBackgroundColor(Color.TRANSPARENT);
model.setChecked(false);
}
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Model s = item.get(getAdapterPosition());
if (!selectList.contains(s)){
selectList.add(s);
model.setChecked(true);
} else {
selectList.remove(s);
model.setChecked(false);
}
notifyItemChanged(getAdapterPosition());
}
});
public class Model {
private boolean isChecked = false;
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
}
Don't manually change the design in the onclick listener, just update your model (as you are already doing: model.setchecked(...) depending on state)
Then call Adapter.notifyItemChanged(getAdapterPosition())
This will force the adapter to reload the item, calling onBindViewHolder, where the design should be updated properly
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Model s = item.get(getAdapterPosition());
if (!selectList.contains(s)){
selectList.add(s);
model.setChecked(true);
} else {
selectList.remove(s);
model.setChecked(false);
}
adapter.notifyItemChanged(getAdapterPosition())
}
In the above example, replace "adapter" with a reference to your recylerview adapter

Spinner in RecyclerView to update item values

How can I update the values in my Dataset from a Spinner selection in a RecyclerView? Should I be using LiveData and Room with notifyItemChange(), data binding, or something simpler? I have a Horseclass and a HorseData class. The number of items is static and the options for the variables are static. I do not need to add values or items, I just need to be able to select the variable WinPercentHorse for each item and have that value saved back to the dataset.
public class HorseAdapter extends RecyclerView.Adapter<HorseViewHolder> {
private AdapterView.OnItemSelectedListener onItemSelectedListener;
//we are storing all the horses in a list
private List<Horse> horseList;
//this context we will use to inflate the layout
private Context mCtx;
//getting the context and product list with constructor
public HorseAdapter(Context mCtx, List<Horse> horseList) {
this.mCtx = mCtx;
this.horseList = horseList;
}
#Override
public HorseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.item_layout, null);
return new HorseViewHolder(view);
}
#Override
public void onBindViewHolder(final HorseViewHolder holder, final int position) {
//getting the product of the specified position
Horse horse = horseList.get(position);
//binding the data with the viewholder views
holder.ViewWinPercent.setText(String.valueOf(horse.getWinPercentHorse()));
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(horse.getImgHorse()));
holder.ViewValueLine.setText(String.valueOf(horse.getValueOdds()));
holder.itemView.setTag(horse.getId());
holder.spinnerView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
// Update winPercent of item On selecting a spinner item
Toast.makeText(mCtx, "Spinner Selection =" + l + "item selected =" + position, Toast.LENGTH_SHORT).show();
//How to update the WinPercentHorse variable for this item in the horseList
//Then refresh the item notifyItemChange(position, object payload)?
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
#Override
public int getItemCount() {
return horseList.size();
}
public void setHorseList(List<Horse> horseList) {
this.horseList = horseList;
notifyDataSetChanged();
}
}
class HorseViewHolder extends RecyclerView.ViewHolder {
TextView ViewWinPercent, ViewValueLine;
ImageView imageView;
Spinner spinnerView;
public HorseViewHolder(View itemView) {
super(itemView);
ViewWinPercent = itemView.findViewById(R.id.winPercentHorse);
ViewValueLine = itemView.findViewById(R.id.valueLine);
imageView = itemView.findViewById(R.id.imgHorse);
spinnerView=itemView.findViewById(R.id.spinner);
}
}

how to get value from one adapter to another adapter using recyclerview in android?

How to get value from one adapter to another adapter when clicking on the favorite button then it shows how many we clicked on favorite image button and also shows all data in another activity. Below is my Adapter Class & ViewHolder class (i.e AdapterFav.java & ContactViewHolder.java)
AdapterFav.java
public class AdapterFav extends
RecyclerView.Adapter<AdapterFav.ContactViewHolder>{
private ArrayList<Contactfav> contactfavList;
private static Context mContext;
public AdapterFav(ArrayList<Contactfav> contactfavList, Context applicationContext) {
this.contactfavList = contactfavList;
this.mContext = applicationContext;
}
#Override
public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.contact_row, null);
ContactViewHolder contactViewHolder = new ContactViewHolder(view);
return contactViewHolder;
}
#Override
public void onBindViewHolder(ContactViewHolder holder, int position) {
Contactfav contactfav = (Contactfav) contactfavList.get(position);
holder.tvContactName.setText(contactfav.getContactName());
holder.tvPhoneNumber.setText(contactfav.getContactNumber());
//Log.e("Id is", contactfav.getContactNumber());
holder.ivContactImage.setImageBitmap(contactfav.getContactImage());
holder.id=contactfav.getCid();
}
#Override
public int getItemCount() {
return contactfavList.size();
}
}
ContactViewHolder.java
public static class ContactViewHolder extends RecyclerView.ViewHolder {
ImageView ivContactImage;
ImageButton ibFavBtn;
TextView tvContactName;
TextView tvPhoneNumber;
Contactfav contactfav=new Contactfav();
String id;
public ContactViewHolder(View itemView) {
super(itemView);
ivContactImage = (ImageView) itemView.findViewById(R.id.ivContactImage);
tvContactName = (TextView) itemView.findViewById(R.id.tvContactName);
tvPhoneNumber = (TextView) itemView.findViewById(R.id.tvPhoneNumber);
ibFavBtn = (ImageButton) itemView.findViewById(R.id.fav);
ibFavBtn.setOnClickListener(new View.OnClickListener() {
Boolean b = true;
#Override
public void onClick(View view) {
if (b == true) {
ibFavBtn.setImageResource(R.drawable.star2);
Log.e("From get", id);
b = false;
} else {
ibFavBtn.setImageResource(R.drawable.star);
b = true;
}
}
});
}
}

Android recycleView displaying an emply list

Please i need help on this one. Have been working on it for days but cant figure it out.
I have a recycleView to display a list of names but its displaying empty list, but i can print the list in console.
here,s the code fetching the list
public List<BackendlessUser> userList = new ArrayList<BackendlessUser>();
BackendlessDataQuery query = new BackendlessDataQuery();
Backendless.Data.of( BackendlessUser.class ).find( query, new AsyncCallback<BackendlessCollection<BackendlessUser>>()
{
#Override
public void handleResponse( BackendlessCollection<BackendlessUser> response )
{
userList = response.getCurrentPage();
for( BackendlessUser user : userList ){
Log.d( "USERS : ", user.getEmail() );
}
Log.d("USER LIST", String.valueOf( userList.size() ));
}
#Override
public void handleFault(BackendlessFault backendlessFault) {
}
});
and the recyclerView adapter that is supposed to adapt the list to the view ..
private void setupRecyclerView(#NonNull RecyclerView recyclerView) {
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(userList));
}
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final List<BackendlessUser> mValues;
public SimpleItemRecyclerViewAdapter(List<BackendlessUser> items) {
mValues = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_content, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).getProperty("idno").toString());
holder.mContentView.setText(mValues.get(position).getProperty("fname").toString());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getProperty("idno").toString());
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
Context context = v.getContext();
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getProperty("idno").toString());
context.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public BackendlessUser mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}

RecycleView , some items' subView doesn't show correctly

in fragment
mAdapter = new MessageAdapter(this);
mRV.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false));
mRV.setItemAnimator(new DefaultItemAnimator());
DividerItemDecoration itemDecoration = new DividerItemDecoration.Builder()
.setOffsetLeft(ScreenUtil.dip2px(getActivity(), 60 + 10) + this.getResources().getDimensionPixelOffset(R.dimen.horizontal_margin))
.build(getActivity());
mRV.addItemDecoration(itemDecoration);
mRV.setItemViewCacheSize(15);
mRV.setAdapter(mAdapter);
in adapter
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MessageItemHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.w_message_item,parent,false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((RVItemInterface)holder).setAdapter(this);
((RVItemInterface)holder).update(dataList.get(position),position);
}
in holder
public class MessageItemHolder extends RecyclerView.ViewHolder implements RVItemInterface{
private RoundAvatar mAvatar;
private TextView mTitle;
private TextView mContent;
private TextView mTime;
private BaseRVAdapter mAdapter;
private MsgDecorVo mMsgDecorVo;
...
#Override
public void update(Object obj, final int position) {
reset();
mMsgDecorVo = (MsgDecorVo) obj;
if(mMsgDecorVo.type == MsgDecorVo.TYPE_CATEGORY){
updateCategory();
MsgVo msgVo = mMsgDecorVo.msgVo;
if(msgVo.getMsg() == null || msgVo.getMsg().equals("")){
mContent.setVisibility(View.GONE);
}else {
mContent.setVisibility(View.VISIBLE);
mContent.setText(msgVo.getMsg());
}
if(msgVo.getTime() == 0){
mTime.setVisibility(View.GONE);
}else {
mTime.setVisibility(View.VISIBLE);
mTime.setText(TimeUtil.transformLong2DateString(msgVo.getTime()));
}
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dealCategoryClick();
}
});
}else if(mMsgDecorVo.type == MsgDecorVo.TYPE_CONVERSATION){
...
mContent.setText(ImUtil.getMsgContent(message));
mTime.setText(TimeUtil.transformLong2DateString(message.getMsgTime()));
if(chatUserVo != null){
..
}else {
..
}
}
}
//
private void updateCategory(){
...
}
//
private void dealCategoryClick(){
...
}
#Override
public void setAdapter(RecyclerView.Adapter adapter) {
mAdapter = (BaseRVAdapter) adapter;
}
#Override
public void reset() {
mAvatar.setOnClickListener(null);
mAvatar.setAvatar(R.drawable.avatar_default_circle);
mAvatar.hideTagBottom();
mAvatar.hideTagTop();
}
}
these code in holder
mContent.setText(ImUtil.getMsgContent(message));
mTime.setText(TimeUtil.transformLong2DateString(message.getMsgTime()));
has run
but when I scrolled,some of items doesn't show correctly ,the time and content was gone!
if I notify the recyclerview ,it goes right, and if i scroll again,it will still be wrong
just like the image,you can see some items' (time & content) was gone!
http://g.picphotos.baidu.com/album/s%3D900%3Bq%3D90/sign=297cc7510946f21fcd345253c61f1a5d/a686c9177f3e6709378bcc5538c79f3df9dc5595.jpg "tooltip"
Well, you don't have the full code but I assume it is happening because you are not resetting your view states properly.
For Instance, in your updateCode, if type = TYPE_CATEGORY, you set the mTime's visibility depending on whether getTime is 0 or not. But as you scroll, that row might be re-used for
TYPE_CONVERSATION in which case, mTime's visibility will NOT be updated.