I had some problem about scrolling with Card inside RecyclerView. There some additional gaps when I scroll inside the RecyclerView, you can see it in this gif:
This is my adapter. Is this because the fragment or what ?
public class PosItemAdapter extends RecyclerView.Adapter<PosItemAdapter.MyViewHolder> {
private List<Item> itemList;
private ArrayList<CartItem> cartList;
private Boolean isMixed = false;
public class MyViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public ImageView picture;
public TextView name;
public TextView desc;
public TextView price;
public MyViewHolder(View view) {
super(view);
mView = view;
picture = (ImageView) view.findViewById(R.id.list_pos_item_picture);
name = (TextView) view.findViewById(R.id.list_pos_item_name);
price = (TextView) view.findViewById(R.id.list_pos_item_price);
}
}
public PosItemAdapter(ArrayList<Item> itemList, Boolean isMixed) {
this.itemList = itemList;
this.isMixed = isMixed;
}
public Item getValueAt(int position) {
return itemList.get(position);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_pos_item_layout, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
#Override
public int getItemCount() {
if (itemList != null) {
return itemList.size();
} else {
return 0;
}
}
}
Solved, the problem was my card height. I set to wrap_content and the glitch fixed.
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());
}
});
}
}
}
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.
I'm using recycleview for populating my items. I'm trying to use notifyItemRemoved to remove an item from my recycleview but it does not hide the row and it doesn't notify the adapter .this is my adapter code :
public class CatsAdapter extends RecyclerView.Adapter<CatsAdapter.MyViewHolder> {
private LayoutInflater inflater;
private List<CatItems> list;
public CatsAdapter(Context context, List<CatItems> feedItemList) {
inflater = LayoutInflater.from(context);
this.list = feedItemList;
}
public void addAll(List<CatItems> catItems) {
if (this.list == null) {
this.list = catItems;
} else {
this.list.addAll(catItems);
}
notifyDataSetChanged();
notifyItemInserted(list.size());
}
public void remove(int pos) {
this.list.remove(pos);
notifyItemRemoved(pos);
notifyItemRangeChanged(pos, getItemCount()-pos);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parrent, int i) {
View view = inflater.inflate(R.layout.row_grid2, parrent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(final MyViewHolder viewHolder, final int position) {
CatItems item = list.get(position);
viewHolder.del.setTag(item.getId());
viewHolder.del.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
adapter.remove(position);
}
});
}
#Override
public int getItemCount() {
if (list == null)
return 0;
else
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView img, ten, five,del;
public MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
del = (ImageView) itemView.findViewById(R.id.del);
}
}
}
Where is the problem ?
In RecyclerView.Adapter i need to change favIcon in each row list that after select each position just specified row favIcon change.
All thing is right but when scroll RecyclerView , position of selected row change automatically!
it's my adapter class :
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ItemData[] itemsData;
Activity activity;
public MyAdapter(Activity activity, ItemData[] itemsData) {
this.activity=activity;
this.itemsData = itemsData;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, null);
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
viewHolder.txtViewTitle.setText(itemsData[position].getTitle());
viewHolder.imgViewIcon.setImageResource(itemsData[position].getImageUrl());
viewHolder.imgViewIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!viewHolder.isFav) {
Toast.makeText(activity,"Selected Row : "+position,Toast.LENGTH_SHORT).show();
viewHolder.isFav = true;
viewHolder.imgViewIcon.setImageResource(R.drawable.icon_fav);
} else {
viewHolder.imgViewIcon.setImageResource(R.drawable.pre_ic_ab_drawer);
viewHolder.isFav = false;
}
}
});
if (viewHolder.isFav)
viewHolder.imgViewIcon.setImageResource(R.drawable.icon_fav);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtViewTitle;
public ImageView imgViewIcon;
public Boolean isFav=false;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
}
}
#Override
public int getItemCount() {
return itemsData.length;
}
}
What I see in the output :
As seen i select first row icon , but after scroll RecyclerView , selected position change.
Then try to use changing favIconand imgViewIcon.setOnClickListener in onCreateViewHolder again wrong position!
Too i try to store position in sharedPreferences or modelClass , but this return wrong position in scrolling yet
There is a way to avoid this problem?
I saw this solution Too :Get clicked item and its position in RecyclerView
Try to use your model ItemData[] itemsData; to save if element is selected.
eg.
if (itemsData[position].isFav){
viewHolder.imgViewIcon.setImageResource(R.drawable.icon_fav);
}else{
viewHolder.imgViewIcon.setImageResource(R.drawable.pre_ic_ab_drawer);
}
viewHolder.imgViewIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!itemsData[position].isFav) {
Toast.makeText(activity,"Selected Row : "+position,Toast.LENGTH_SHORT).show();
itemsData[position].isFav = true;
viewHolder.imgViewIcon.setImageResource(R.drawable.icon_fav);
} else {
viewHolder.imgViewIcon.setImageResource(R.drawable.pre_ic_ab_drawer);
itemsData[position].isFav = false;
}
}
});
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ItemData[] itemsData;
Activity activity;
public MyAdapter(Activity activity, ItemData[] itemsData) {
this.activity=activity;
this.itemsData = itemsData;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, null);
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
viewHolder.txtViewTitle.setText(itemsData[position].getTitle());
viewHolder.imgViewIcon.setImageResource(itemsData[position].getImageUrl());
viewHolder.imgViewIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!viewHolder.isFav) {
Toast.makeText(activity,"Selected Row : "+position,Toast.LENGTH_SHORT).show();
viewHolder.isFav = true;
viewHolder.imgViewIcon.setImageResource(R.drawable.icon_fav);
} else {
viewHolder.imgViewIcon.setImageResource(R.drawable.pre_ic_ab_drawer);
viewHolder.isFav = false;
}
}
});
if (viewHolder.isFav)
viewHolder.imgViewIcon.setImageResource(R.drawable.icon_fav);
else
// The change
viewHolder.imgViewIcon.setImageResource(R.drawable.pre_ic_ab_drawer);
}
When you bind the ViewHolder you should reset the ImageView icon if it's not fav.
I have an array of 600 items. I have put all the array items in a RecyclerView and they are scrolling well. But, when I try to access onClick listener it is not getting called. I also tried to Implement View.OnClickListener and Override onClick in my ViewHolder class, but its not working.
I want to Toast data of the clicked item in the list when user clicks one of the items in the view
Adapter code is
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
private String mItem;
private TextView mTextView;
public ViewHolder(View view) {
super(view);
view.setOnClickListener(this);
mTextView = (TextView) view.findViewById(R.id.item_title);
}
public void setItem(String item) {
mItem = item;
mTextView.setText(item);
}
#Override
public void onClick(View view) {
Log.d("TAG", "onClick " + getPosition() + " " + mItem);
}
}
private String[] mDataset;
public MyAdapter(String[] dataset) {
mDataset = dataset;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.setItem(mDataset[position]);
}
#Override
public int getItemCount() {
return mDataset.length;
}
}
Try this..
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder
{
private String mItem;
private TextView mTextView;
public ViewHolder(View view) {
super(view);
mTextView = (TextView) view.findViewById(R.id.item_title);
}
public void setItem(String item) {
mItem = item;
mTextView.setText(item);
}
private String[] mDataset;
Context context;
public MyAdapter(Context context,String[] dataset) {
this.context=context;
mDataset = dataset;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.setOnClickListener(new ItemClicklistener(position);
holder.setItem(mDataset[position]);
}
#Override
public int getItemCount() {
return mDataset.length;
}
class ItemClicklistener implements View.OnClickListener {
private int position;
ItemClicklistener(int position) {
this.position = position;
}
#Override
public void onClick(View view) {
Toast.makeText(context,"OnClick :"+position,Toast.LENGTH_SHORT).show();
}
}
}
public class MyAdapter extends RecyclerView.Adapter {
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
private List<MyModel> list;
View v1;
RecyclerView.ViewHolder vh;
public MyAdapter(List<MyModel> lists) {
list = lists;
}
#Override
public int getItemViewType(int position) {
return list.get(position) != null ? VIEW_ITEM : VIEW_PROG;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
if (viewType == VIEW_ITEM) {
v1 = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item, parent, false);
vh = new MyViewHolder(v1);
return vh;
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof MyViewHolder) {
final MyModel mymodel= (MyModel) list.get(position);
((MyViewHolder) holder).mTextView.setText(mymodel.getItem());
((MyViewHolder) holder).mTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("TAG", "onClick " + Integer.toString(position) + " " + mymodel.getItem());
}
});
}
}
#Override
public int getItemCount() {
return list.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView;
public MyViewHolder(View view) {
super(view);
mTextView = (TextView) view.findViewById(R.id.item_title);
}
}
}
// List Item Stored
public class MyModel extends Application implements Serializable {
private static final long serialVersionUID = 1L;
private String item,
public MyModel() {}
public MyModel(String itemtext) {
this.item = itemtext;
}
public String getItem() {return item;}
public void setItem(String id){ this.item = item;}
}
//use this code in main activity
List<MyModel> Listitem = new ArrayList<CarListGetterSetter>();
for(int i=0;i<600;i++){
Listitem.add(new MyModel("hi"+i);
}
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
MyAdapter mAdapter = new MyAdapter(Listitem);
recyclerView.setAdapter(mAdapter);
You can implement your RecyclerView adapter this way to support for onItemCLick and OnItemLongClick
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder>{
ArrayList<Person> data;
Context context;
HashMap<String, Integer> screenDetails;
private static ClickListener clickListener;
public interface ClickListener {
void onItemClick(int position, View v);
void onItemLongClick(int position, View v);
}
public void setOnItemClickListener(ClickListener clickListener) {
PersonAdapter.clickListener = clickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
public View view;
TextView full_name;
public ViewHolder(View v) {
super(v);
view = v;
full_name = (TextView)view.findViewById(R.id.first_name);
v.setOnClickListener(this);
v.setOnLongClickListener(this);
}
#Override
public void onClick(View v) {
clickListener.onItemClick(getAdapterPosition(), v);
}
#Override
public boolean onLongClick(View v) {
clickListener.onItemLongClick(getAdapterPosition(), v);
return false;
}
}
public PersonAdapter(Context context, ArrayList<Person> data) {
this.context = context;
this.data = data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View cardView = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_chatroom_item, parent, false);
return new ViewHolder(cardView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Person person = data.get(position);
}
#Override
public int getItemCount() {
return data.size();
}
}
And in your activity implement it this way
PersonAdapter personAdapter = new PersonAdapter(getApplicationContext(),persons);
personAdapter.setOnItemClickListener(new PersonAdapter.ClickListener() {
#Override
public void onItemClick(int position, View v) {
}
#Override
public void onItemLongClick(int position, View v) {
}
});
recyclerView.setAdapter(PersonAdapter);