Using multiple views and data sets in RecyclerView - java

I have the following adapter which populates a RecyclerView with CardView items containing one TextView. It fills these TextViews with data from a String array. However, now I want to add another TextView to my CardViews and populate it with a separate data array, and I was wondering how I can best achieve this:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private String[] mDataset;
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View itemView) {
super(itemView);
mTextView = (TextView)itemView.findViewById(R.id.grade);
}
}
public RecyclerAdapter(String[] myDataset) {
mDataset = myDataset;
}
#Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_item, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(mDataset[position]);
}
#Override
public int getItemCount() {
return mDataset.length;
}
}
All help is appreciated as always!

Simply add another TextView or any other view in your CardLayout XML R.layout.card_item
Then
public TextView mTextView;
public TextView mTextView1;
public TextView mTextView2;
public TextView mTextView3;
public ViewHolder(View itemView) {
super(itemView);
mTextView = (TextView)itemView.findViewById(R.id.grade);
mTextView1 = (TextView)itemView.findViewById(R.id.grade1);
mTextView2 = (TextView)itemView.findViewById(R.id.grade2);
mTextView3 = (TextView)itemView.findViewById(R.id.grade3);
}
and finally set data to all the desired textviews as
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText("String");
holder.mTextView1.setText("String");
holder.mTextView2.setText("String");
holder.mTextView3.setText("String");
}

Related

Facing error in onBindView() method in recyclerView

I am just practicing the RecyclerView. when I run the App my App crashed I check the log but i cant understand the problem can some help me im waiting for someone responce?
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
private TextView name,number;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View view) {
super(view);
textView = (TextView) view.findViewById(R.id.name);
}
public TextView getTextView() {
return textView;
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
view.findViewById(R.id.name);
view.findViewById(R.id.number);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
name.setText(localDataSet[position].getName());
number.setText(localDataSet[position].getPhone());
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
You need to change the following things in your code:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
//remove this from here.
//private TextView name,number;
public static class ViewHolder extends RecyclerView.ViewHolder {
//This should be from the layout you have passed in ViewHolder method. in your case from R.layout.contacx. This layout should have two textview with ids:- name and phone respectively.
private final TextView name, phone;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
phone = view.findViewById(R.id.phone);
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
//remvoe this from here.
//view.findViewById(R.id.name);
//view.findViewById(R.id.number);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
//here you should call those view to bind your data like:
viewHolder.name.setText(localDataSet[position].getName());
viewHolder.phone.setText(String.valueOf(localDataSet[position].getPhone()));
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
Use ViewHolder for data bind. More safe
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView name, number;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
number = view.findViewById(R.id.phone);
}
public void bindData(model data) {
name.setText(data.getName());
number.setText(String.valueOf(data.getPhone()));
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
/* No Need
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
view.findViewById(R.id.name);
view.findViewById(R.id.number);
*/
return new ViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false););
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
/*
name.setText(localDataSet[position].getName());
number.setText(localDataSet[position].getPhone());
*/
viewHolder.bindData(localDataSet[position]);
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}

Multiple recyclerviews using one adapter

I have an app where I want to use recyclerviews in different parts of the application and I was thinking of using the same adapter for the same two (or more) recyclerviews, I was thinking this would be a good practice, or am I mistaken and better off making a new adapter for every recyclerview in the app?
Here is the code for my adapter:
public class RecyclerViewAdapter extends RecyclerView.Adapter <RecyclerViewAdapter.MyViewHolder> {
private ArrayList<Task> list;
//This is the list of the second recyclerview which I want to implement
private ArrayList<String> categories;
private OnItemListener mOnItemListener;
RecyclerViewAdapter(ArrayList<Task> list, OnItemListener onItemListener)
{
this.list = list;
this.mOnItemListener = onItemListener;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
TextView textView = (TextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.single_view, parent, false);
return new MyViewHolder(textView, mOnItemListener);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.textView.setText(list.get(position).getTaskName());
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
TextView textView;
OnItemListener onItemListener;
MyViewHolder(#NonNull View itemView, OnItemListener onItemListener) {
super(itemView);
textView = itemView.findViewById(R.id.singleView);
this.onItemListener = onItemListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
onItemListener.onItemClick(getAdapterPosition());
}
}
public interface OnItemListener
{
void onItemClick(int position);
}
}
So how would I go about doing this so that it can switch depending on which recyclerview in the app is setting/initializing the adapter, so that the getItemCount for example, would return the size of categories instead of list and so on.

What might be the problem with my adapter i seem not to find it``

The view seems not to bind to the ArrayList(ie private ArrayList mEvents;) that i passed to the class ,on the onBindViewHolder(ie holder.mTextView2.setText(current.getcity());) i can seem to access the textView variables(ie public TextView mTextview2;), that i declared in the view holder class. I have tried to make the variables as a member variable but it seems not to work well
public class eventsAdapter extends RecyclerView.Adapter {
private ArrayList<recycleview_items> mEvents;
public eventsAdapter(ArrayList<recycleview_items> passedArray){
//constructor for the adapter calls for which i created
mEvents = passedArray;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//we pass the layout of our card to the adapter here
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_listitem, parent, false);
eventViewHolder events = new eventViewHolder(v);
return events;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
//we pass data from the array list we created to the views
recycleview_items current = mEvents.get(position);
holder.mImageView.setImageResource(current.getImageResource());
holder.mTextView1.setText(current.getname());
holder.mTextView2.setText(current.getcity());
}
#Override
public int getItemCount() {
return mEvents.size();
};
public static class eventViewHolder extends RecyclerView.ViewHolder{
public ImageView mImageview ;
public TextView mTextview;
public TextView mTextview2;
public eventViewHolder(#NonNull View itemView) {
super(itemView);
mImageview = itemView.findViewById(R.id.ImageView1);
mTextview = itemView.findViewById(R.id.text_view1);
mTextview2 = itemView.findViewById(R.id.text_view2);
}
}
}
public class eventsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<recycleview_items> mEvents;
public eventsAdapter(ArrayList<recycleview_items> passedArray){
//constructor for the adapter calls for which i created
mEvents = passedArray;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//we pass the layout of our card to the adapter here
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_listitem, parent, false);
eventViewHolder events = new eventViewHolder(v);
return events;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
//we pass data from the array list we created to the views
recycleview_items current = mEvents.get(position);
holder.bind(current);
}
#Override
public int getItemCount() {
return mEvents.size();
};
class eventViewHolder extends RecyclerView.ViewHolder{
public ImageView mImageview ;
public TextView mTextview;
public TextView mTextview2;
public eventViewHolder(#NonNull View itemView) {
super(itemView);
mImageview = itemView.findViewById(R.id.ImageView1);
mTextview = itemView.findViewById(R.id.text_view1);
mTextview2 = itemView.findViewById(R.id.text_view2);
public void bind(recycleview_items item){
//bind your items here
holder.mImageView.setImageResource(item.getImageResource());
holder.mTextView1.setText(item.getname());
holder.mTextView2.setText(item.getcity());
}
}
}
I've rewritten your code for you with slight modifications.
You should create adapter like this
extends RecyclerView.Adapter<eventsAdapter.eventViewHolder >
Also you should edit
public eventViewHolder onCreateViewHolder
And
onBindViewHolder(eventViewHolder holder, int position)
Try this
public class eventsAdapter extends RecyclerView.Adapter<eventsAdapter.eventViewHolder>{
private ArrayList<recycleview_items> mEvents;
public eventsAdapter(ArrayList<recycleview_items> passedArray){
//constructor for the adapter calls for which i created
mEvents = passedArray;
}
#NonNull
#Override
public eventViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_listitem, parent, false);
return new eventViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull eventViewHolder holder, int position) {
recycleview_items current = mEvents.get(position);
holder.mImageview.setImageResource(current.getImageResource());
holder.mTextview.setText(current.getname());
holder.mTextview2.setText(current.getcity());
}
#Override
public int getItemCount() {
return 0;
}
class eventViewHolder extends RecyclerView.ViewHolder {
ImageView mImageview;
TextView mTextview;
TextView mTextview2;
public eventViewHolder(View itemView) {
super(itemView);
mImageview = itemView.findViewById(R.id.ImageView1);
mTextview = itemView.findViewById(R.id.text_view1);
mTextview2 = itemView.findViewById(R.id.text_view2);
}
}
}
Almost every thing was in Your code that's i have done some modification.
Mate see your Holder View Class name its 'eventViewHolder' and for onBindViewHolder and onCreateViewHolder you're accessing the Recycler.ViewHolder so it's very obvious that you can't access those variable just change this..
#Override
public void onBindViewHolder(#NonNull eventsAdapter.eventViewHolder holder, int position) {
.....
}
and in
#NonNull
#Override
public eventsAdapter.eventViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
......
}

Adding some space between 2 rows of a GridLayout

// here is my grid adapter
public class TimeSlotAdapter extends RecyclerView.Adapter {
private LayoutInflater mInflater;
private String strSelectedDate;
List<Boolean> numberList;
private List<String> mData;
private TextView timetv;
List<RelativeLayout> activeTimeSlotsArray=new ArrayList<RelativeLayout>();
// data is passed into the constructor
public TimeSlotAdapter(Context context, List<String> data, String strSelectedDate,TextView timetv,List<Boolean> numberList) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.strSelectedDate = strSelectedDate;
this.timetv=timetv;
this.numberList=numberList;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
return new listViewHolder(view);
}
#SuppressLint("ResourceAsColor")
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if(position==5||position==11){
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0,0,0,100);
((listViewHolder)holder).timeslot.setLayoutParams(params);
}
((listViewHolder) holder).radioButton.setText(mData.get(position));
((listViewHolder)holder).radioButton.setTextColor(R.color.inactiveslots);
((listViewHolder) holder).timeslot.setBackgroundResource(R.drawable.inactive_slots);
}
#Override
public int getItemCount() {
return mData.size();
}
private class listViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
RadioButton radioButton;
RelativeLayout timeslot;
String strStartTime;
int selectedPosition;
public listViewHolder(View itemView) {
super(itemView);
radioButton = itemView.findViewById(R.id.radioBtton);
timeslot = itemView.findViewById(R.id.mslot1);
timeslot.setOnClickListener(this);
radioButton.setOnClickListener(this);
}
}
When i try to give space the size of the button in position 5 and 11 is changed.Here i am giving the space in gridlayout but the button size i don't want to change it should be in same size.Also the i need space between two rows in a grid
Try this:
LayoutParams params = ((listViewHolder)holder).timeslot.getLayoutParams();
params.setMargins(0,0,0,100);
((listViewHolder)holder).timeslot.setLayoutParams(params);
and check R.layout.grid_item file if radioButton layout_width attribute is wrap_content.

Picasso Library Not Working In RecyclerView in android

So im having this issue in my adapter to were when i go to set the Picasso method to convert my image url it will not allow me to pass the context no matter how i do it. i Have tried this and The class name .this neither seem to work. Not sure what or why this is happening. Here is the adapter class that im having issues with.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ContentViewHolder> {
public content[] mDataset;
public MyAdapter(content[] data) {
mDataset = data;
}
#Override
public ContentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.test, parent, false);
ContentViewHolder viewHolder = new ContentViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ContentViewHolder holder, int position) {
holder.bindContent(mDataset[position]);
}
#Override
public int getItemCount() {
return mDataset.length;
}
public class ContentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView mUrl;
public TextView mTitle;
public TextView mDate;
public TextView mAuthor;
public ImageView mThumbnail;
public ContentViewHolder(View itemView) {
super(itemView);
mUrl= (TextView) itemView.findViewById(R.id.url);
mTitle = (TextView) itemView.findViewById(R.id.title);
mDate = (TextView) itemView.findViewById(R.id.date);
mAuthor = (TextView) itemView.findViewById(R.id.author);
mThumbnail =(ImageView)itemView.findViewById(R.id.thumbnail);
}
public void bindContent(content bloginfo) {
mUrl.setText(bloginfo.getUrl());
mTitle.setText(bloginfo.getTitle());
mDate.setText(bloginfo.getDate());
mAuthor.setText(bloginfo.getAuthor());
Picasso.with(context).load(bloginfo.getThumbnail()).into(mThumbnail);
}
#Override
public void onClick(View view) {
}
}
}
Ok so i got this to work here is the working adapter code below. Thank you all for your help.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ContentViewHolder> {
public content[] mDataset;
private Activity activityContext;
public MyAdapter(Activity context,content[] data) {
mDataset = data;
activityContext = context;
}
#Override
public ContentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.test, parent, false);
ContentViewHolder viewHolder = new ContentViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ContentViewHolder holder, int position) {
holder.bindContent(mDataset[position]);
}
#Override
public int getItemCount() {
return mDataset.length;
}
public class ContentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView mUrl;
public TextView mTitle;
public TextView mDate;
public TextView mAuthor;
public ImageView mThumbnail;
public ContentViewHolder(View itemView) {
super(itemView);
mUrl= (TextView) itemView.findViewById(R.id.url);
mTitle = (TextView) itemView.findViewById(R.id.title);
mDate = (TextView) itemView.findViewById(R.id.date);
mAuthor = (TextView) itemView.findViewById(R.id.author);
mThumbnail =(ImageView)itemView.findViewById(R.id.thumbnail);
}
public void bindContent(content bloginfo) {
mUrl.setText(bloginfo.getUrl());
mTitle.setText(bloginfo.getTitle());
mDate.setText(bloginfo.getDate());
mAuthor.setText(bloginfo.getAuthor());
Picasso.with(activityContext).load(bloginfo.getThumbnail()).into(mThumbnail);
}
#Override
public void onClick(View view) {
}
}
}
This
Picasso.with(MyAdapter.this)
should be
Picasso.with(context)
Use Activity Context. This can be passed to the constructor of adapter class from activity.
http://developer.android.com/reference/android/content/Context.html
http://square.github.io/picasso/
Samples available on github
https://github.com/square/picasso/blob/master/picasso-sample/src/main/java/com/example/picasso/PicassoSampleAdapter.java
In your adapter you can make:
private Activity activityContext;
then in Adapter contructor:
public MyAdapter(Activity context, content[] data) {
mDataset = data;
activityContext = context;
}
Finally call:
Picasso.with(activityContext).load(bloginfo.getThumbnail()).into(mThumbnail);
If you create your Adapter in your Activity you need to create it using:
new myAdapter(this, YOURDATA), if you create it in Fragment, you need to use new myAdapter(getActivity(), YOURDATA).
Picasso.with(mThumbnail.getContext()).load(bloginfo.getThumbnail()).into(mThumbnail);

Categories

Resources