Why me recyclerview item automatically click? - java

I am working on an application where i have list of items in recyclerview on items i have a hear icon as wishlist the problem is when i click on the first item the last item automatically selected when i select the second item the second last got selected automatically. I dont know why this is happening?? please guide me
My RecyclerView Adapter
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.Viewholder> {
ArrayList<RecyclerviewModel> datalist;
Context context;
public RecyclerviewAdapter(ArrayList<RecyclerviewModel> datalist, Context context) {
this.datalist = datalist;
this.context = context;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View viewholder = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent , false);
return new Viewholder(viewholder);
}
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
holder.name.setText(datalist.get(position).getName());
holder.email.setText(datalist.get(position).getEmail());
holder.desc.setText(datalist.get(position).getDesc());
holder.book.setText(datalist.get(position).getBook());
//code for setting image-slider on home
holder.sliderAdapterExample = new SliderAdapterExample(context.getApplicationContext(), datalist.get(position).getImages());
holder.imageSlider.setSliderAdapter(holder.sliderAdapterExample);
final RecyclerviewModel datawish = datalist.get(position);
String wishName = datawish.getName();
String wishEmail = datawish.getEmail();
holder.wishlist.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int pos = holder.getBindingAdapterPosition();
if(compoundButton.isChecked())
{
Toast.makeText(context, "item added to wishlist" + pos , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "item removed to wishlist", Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
public int getItemCount() {
return datalist.size();
}
public class Viewholder extends RecyclerView.ViewHolder{
TextView name, email, desc, book;
SliderView imageSlider;
SliderAdapterExample sliderAdapterExample;
CheckBox wishlist;
public Viewholder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
email = itemView.findViewById(R.id.text_email);
desc = itemView.findViewById(R.id.text_desc);
book = itemView.findViewById(R.id.text_book);
wishlist = itemView.findViewById(R.id.wishlist_checkbox);
imageSlider = itemView.findViewById(R.id.imageView3);
}
}
}
i click on the first heart icon
the last one is automatically clicked

Why this happening? Because when you scroll recyclerview remove hidden items automatically. For ex: 0 will be remove when scroll down and 1 item will be 0, 2 item will be 1 and 3->2,4->3 like this. There are 2 ways fix this error:
1) Simple way, but this method freeze your app when data is big:
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
holder.setIsRecyclable(false);
}
2) If you want you use second method you must add unique_id to your arraylist each item:
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.Viewholder> {
ArrayList<RecyclerviewModel> datalist;
Context context;
private ArrayList<String> checkedItems=new ArrayList<>();
public RecyclerviewAdapter(ArrayList<RecyclerviewModel> datalist, Context context) {
this.datalist = datalist;
this.context = context;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View viewholder = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent , false);
return new Viewholder(viewholder);
}
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
int pos=holder.getAdapterPosition();
holder.name.setText(datalist.get(pos).getName());
holder.email.setText(datalist.get(pos).getEmail());
holder.desc.setText(datalist.get(pos).getDesc());
holder.book.setText(datalist.get(pos).getBook());
//code for setting image-slider on home
holder.sliderAdapterExample = new SliderAdapterExample(context.getApplicationContext(), datalist.get(pos).getImages());
holder.imageSlider.setSliderAdapter(holder.sliderAdapterExample);
final RecyclerviewModel datawish = datalist.get(pos);
String wishName = datawish.getName();
String wishEmail = datawish.getEmail();
holder.wishlist.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
checkedItems.add(datalist.get(pos).getUniqueId());
} else {
checkedItems.remove(datalist.get(pos).getUniqueId());
}
}
});
// Check your selection here
if(checkedItems.contains(datalist.get(pos).getUniqueId())){
holder.wishlist.setChecked(true);
} else {
holder.wishlist.setChecked(false);
}
}
#Override
public int getItemCount() {
return datalist.size();
}
public class Viewholder extends RecyclerView.ViewHolder{
TextView name, email, desc, book;
SliderView imageSlider;
SliderAdapterExample sliderAdapterExample;
CheckBox wishlist;
public Viewholder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
email = itemView.findViewById(R.id.text_email);
desc = itemView.findViewById(R.id.text_desc);
book = itemView.findViewById(R.id.text_book);
wishlist = itemView.findViewById(R.id.wishlist_checkbox);
imageSlider = itemView.findViewById(R.id.imageView3);
}
}
}

When you call your Adapter in your Fragment or Activity, add this line before setAdapter()
recyclerView.setItemViewCacheSize(mData.size());

Related

Android Studio: Deleting Item from ChildRecyclerView

I'm currently building a schedule app where users can input information, and the app will organize the information in a list with each day of the week as the header with each corresponding activity under the day. I'm using a parent child recyclerview to do this (i.e. each day of the week is a part of the parent recyclerview and each activity in the schedule is part of the child recyclerview). Right now I'm trying to add a swipe to delete information in the child recyclerview. Does anyone know how I would go about doing this using the parent child recyclerview configuration, where I have two different adapters for each recyclerview?
Code for Parent RecyclerView:
public class MainRecyclerViewAdapter extends RecyclerView.Adapter<MainRecyclerViewAdapter.ViewHolder> {
ArrayList<DayHeader> weekList;
private Context mContext;
public MainRecyclerViewAdapter(Context mContext, ArrayList<DayHeader> weekList) {
this.mContext = mContext;
this.weekList = weekList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.dayofweekheader,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
DayHeader section = weekList.get(position);
String nameofday = section.getDayName();
ArrayList<medinfo> meditems = section.getmMedItems();
holder.weekdayname.setText(nameofday);
MedicationAdapter childrecyclerAdapter = new MedicationAdapter(mContext,meditems);
holder.childrecyclerview.setAdapter(childrecyclerAdapter);
}
#Override
public int getItemCount() {
return weekList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView weekdayname;
RecyclerView childrecyclerview;
public ViewHolder(#NonNull View itemView) {
super(itemView);
weekdayname = itemView.findViewById(R.id.weekdayheader);
childrecyclerview = itemView.findViewById(R.id.childrecyclerview);
}
}
}
Code for Child RecyclerView:
public class MedicationAdapter extends RecyclerView.Adapter<MedicationAdapter.MedicationViewHolder>{
private ArrayList<medinfo> mMedList;
private Context mContext;
public static class MedicationViewHolder extends RecyclerView.ViewHolder {
public TextView mMedname;
public TextView mTime;
public TextView mNumbPills;
public ImageView popup;
public MedicationViewHolder(#NonNull View itemView) {
super(itemView);
mMedname = itemView.findViewById(R.id.medname);
mTime = itemView.findViewById(R.id.time);
mNumbPills = itemView.findViewById(R.id.numberofpills);
popup = itemView.findViewById(R.id.menumore);
}
}
public MedicationAdapter(Context mContext, ArrayList<medinfo> medList) {
this.mContext = mContext;
this.mMedList = medList;
}
#NonNull
#Override
public MedicationViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item,parent,false);
MedicationViewHolder mvh = new MedicationViewHolder(v);
return mvh;
}
#Override
public void onBindViewHolder(#NonNull MedicationViewHolder holder, int position) {
medinfo currentItem = mMedList.get(position);
String medName = "Medication: " + currentItem.getmMedName();
holder.mMedname.setText(medName);
String medTime = "Time: " + currentItem.getmTime();
holder.mTime.setText(medTime);
String numbPills = "# of Pills: " + currentItem.getmNumbPills();
holder.mNumbPills.setText(numbPills);
}
#Override
public int getItemCount() {
return mMedList.size();
}
public void removeItem(int position) {
mMedList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,mMedList.size());
}
}
I also have this SwipeItem class:
public class SwipeItem extends ItemTouchHelper.SimpleCallback {
MedicationAdapter mMedAdapter;
SwipeItem(MedicationAdapter mMedAdapter){
super(0,ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT);
this.mMedAdapter = mMedAdapter;
}
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getBindingAdapterPosition();
this.mMedAdapter.removeItem(position);
}
}
So how can I implement the SwipeItem in my adapter codes to delete each child item?

Change RecyclerView Selected Item background

i have a list and i showed that in recycler view
some of items have blue background and other items have gray background
i want to edit selected item background (
The selected item means the item that has been clicked )
this is my adapter class
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
private Context context;
private List<User> users = new ArrayList<>();
public UserAdapter(List<User> users, Context context) {
this.users = users;
this.context = context;
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new UserViewHolder(LayoutInflater.from(context).inflate(R.layout.item_user, parent, false));
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
holder.binUser(users.get(position), position);
}
#Override
public int getItemCount() {
return users.size();
}
public class UserViewHolder extends RecyclerView.ViewHolder {
private TextView tvName;
private RelativeLayout rlItemUser;
public UserViewHolder(#NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_itemUser_name);
rlItemUser = itemView.findViewById(R.id.itemUser_rootView);
}
public void binUser(User user, int position){
tvName.setText(user.getName());
if (user.getMode().equals("passenger")){
rlItemUser.setBackgroundColor(context.getResources().getColor(R.color.colorGray));
tvName.setTextColor(context.getResources().getColor(R.color.colorPrimary));
} else if (user.getMode().equals("driver")){
rlItemUser.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
tvName.setTextColor(context.getResources().getColor(R.color.colorGray));
}
}
}
in the bindUser method:
rlItemUser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rtlItemUser.setBackgroundColor(context.getResources().getColor(your color);
adapter.notifyItemChanged(position);
}
});

Getting id of a selected recyclerView item android

I have made a note app and everything works fine. Just in RecyclerView List when I choose an item or items and in menu I click delete button I the note is not deleted. Although delete method works in another place.
Here's the method of delete button in menu :
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.delete_selected) {
for (NotePad notePad : notes) {
if (selectedIds.contains(notePad.getId())) {
database = new Database(this);
database.deleteNote(notePad.getId());
}
}
adapter.notifyDataSetChanged();
return true;
}
return false;
}
And method of delete note in my database class:
void deleteNote(long id) {
SQLiteDatabase database = this.getWritableDatabase();
database.delete(DATABASE_TABLE, ID + "=?", new String[] {String.valueOf(id)});
database.close();
}
I don't know how to relate id of selected note to my method cause deletNote method receives long value but my selectedId is List.
Thanks in advance.
UPDATED
I realized my code works find but it doesn't refresh the list and also goes back from ActionMode to Toolbar. I tried adapter.notifyDataSetChanged();
Use this adapter. I have used interface.
public class NotePadAdapter extends RecyclerView.Adapter < NotePadAdapter.ViewHolder > {
private Context context;
private LayoutInflater inflater;
private List < NotePad > notes;
private List < Long > selectedIds = new ArrayList < > ();
private NoteClickListener listener;
NotePadAdapter(Context context, NoteClickListener listener, List < NotePad > notes) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.notes = notes;
this.listener = listener;
}
public interface NoteClickListener {
public void onNoteClick(NotePad notePad);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.notes_list, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
String title = notes.get(position).getTitle();
String date = notes.get(position).getDate();
String time = notes.get(position).getTime();
holder.setOnClickListener() {
listener.onNoteClick(notes.get(position))
}
holder.noteTitle.setText(title);
holder.noteTitle.setText(title);
holder.noteDate.setText(date);
holder.noteTime.setText(time);
long id = notes.get(position).getId();
if (selectedIds.contains(id)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
holder.rooView.setForeground(new ColorDrawable(ContextCompat.getColor(context, R.color.colorControlActivated)));
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
holder.rooView.setForeground(new ColorDrawable(ContextCompat.getColor(context, android.R.color.transparent)));
}
}
}
#Override
public int getItemCount() {
return notes.size();
}
public NotePad getItem(int position) {
return notes.get(position);
}
public void setSelectedIds(List < Long > selectedIds) {
this.selectedIds = selectedIds;
notifyDataSetChanged();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView noteTitle, noteDate, noteTime;
ConstraintLayout rooView;
ViewHolder(#NonNull View itemView) {
super(itemView);
noteTitle = itemView.findViewById(R.id.note_title);
noteDate = itemView.findViewById(R.id.note_date);
noteTime = itemView.findViewById(R.id.note_time);
rooView = itemView.findViewById(R.id.root_view);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(v.getContext(), ContentActivity.class);
i.putExtra("ID", notes.get(getAdapterPosition()).getId());
v.getContext().startActivity(i);
}
});
}
}
}
In your activity/fragment where you are initiating this adapter pass this for the listener and implement the interface and whenever you click any item on the recyclerview then you will your whole NotePad object inside this function.

How to show an onClick message when clicking on an item of my RecyclerView list?

I am actually working on a group project and I want to develop a functionnality for our application. My goal is to have a list of several items with their images and when I click on an Item of that list I want to have a text pop in the midle of the screen related to that particular item. I'm afraid I might be using the wrong technical Tools to do so. I am actually using a csv file for the list details, an adapter and a viewHolder for the list. Since I have no idea on what is wrong and what to do I link a big part of my code so you can check how I did until now. I can also give you my xml files if you need to check them out, a really big thanks in advance to all the answers and time spent on my problem
I already managed to have my list of items with the title and the picture (text from csv file) of each list item but I'm stuck on how to show a specific text for each ViewHolder.
this is my Adapter
public class Adapter extends RecyclerView.Adapter<ViewHolder> {
List<Departement> list;
Activity activity;
public Adapter(List<Departement> list, Activity activity) {
this.list = list;
this.activity = activity;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int itemType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.departement,viewGroup,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Departement departement = list.get(position);
viewHolder.bind(departement, activity);
}
#Override
public int getItemCount() {
return list.size();
}
}
my ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView textViewView;
private ImageView imageView;
public ViewHolder(View itemView) {
super(itemView);
textViewView = (TextView) itemView.findViewById(R.id.text);
imageView = (ImageView) itemView.findViewById(R.id.image);
}
public void bind(Departement departement, Activity activity){
textViewView.setText(departement.getText());
String uri = departement.getImageUrl();
int imageResource = activity.getResources().getIdentifier(uri, null, activity.getPackageName());
Drawable res = activity.getResources().getDrawable(imageResource);
imageView.setImageDrawable(res);
}
}
each item of the list is a Departement
public class Departement {
private String text;
private String imageUrl;
public Departement(String text, String imageUrl) {
this.text = text;
this.imageUrl = imageUrl;
}
public String getText() {
return text;
}
public String getImageUrl() {
return imageUrl;
}
public void setText(String text) {
this.text = text;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
and finally my fragment
public class FragmentEspecesProches extends Fragment {
public final static char SEPARATOR=',';
private RecyclerView recyclerView;
private List<Departement> departementsList = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_especes_proches, container, false);
ajouterDepartements();
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(this,2));
recyclerView.setAdapter(new Adapter(departementsList, getActivity()));
return view;
}
private void ajouterDepartements() {
ArrayList<String> lines = new ArrayList<>();
ArrayList<String[]> data = new ArrayList<>();
String sep = new Character(SEPARATOR).toString();
lines = UtilitaireResultat.readFile(getActivity().getResources().openRawResource(R.raw.departement));
for(String line : lines){
String[] oneData = line.split(sep);
data.add(oneData);
}
for(int i=0 ; i<data.size() ; i++){
String[] tabStr = data.get(i);
departementsList.add( new Departement( tabStr[2]+" - "+tabStr[3] ,"#drawable/"+tabStr[5] ));
}
}
}
you can implement item click listener like this
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView tvName;
public TextView tvHometown;
private Context context;
public ViewHolder(Context context, View itemView) {
super(itemView);
this.tvName = (TextView) itemView.findViewById(R.id.tvName);
this.tvHometown = (TextView) itemView.findViewById(R.id.tvHometown);
// Store the context
this.context = context;
// Attach a click listener to the entire row view
itemView.setOnClickListener(this);
}
// Handles the row being being clicked
#Override
public void onClick(View view) {
int position = getAdapterPosition(); // gets item position
// if (position != RecyclerView.NO_POSITION) { // Check if an item was deleted, but the user clicked it before the UI removed it
User user = users.get(position);
// We can access the data within the views
Toast.makeText(context, tvName.getText(), Toast.LENGTH_SHORT).show();
// }
}
}
Use onBindViewHolder to handle any interaction on your list items
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Departement departement = list.get(position);
viewHolder.bind(departement, activity);
viewHolder.itemView.setOnClickListener(//your action//);
}
ItemView is the whole item; you can access your textviews or imageviews as you use it on your bind method,
You can use your bind method to apply listeners.
Handle on click of the item inside your ViewHolder constructor
like ,
public ViewHolder(View itemView) {
super(itemView);
textViewView = (TextView) itemView.findViewById(R.id.text);
imageView = (ImageView) itemView.findViewById(R.id.image);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position=getAdapterPosition();
Toast.makeText(context, list.get(position).getText(), Toast.LENGTH_SHORT).show();
}
});
}
Create your onClickListner interface as
interface RecylerViewItemClickListner
{
void onItemClick(Department item)
}
set the listner in Adapter class
private final RecylerViewItemClickListner mOnClickListener;
public Adapter(List<Departement> list, Activity activity) {
this.list = list;
this.activity = activity;
this.mOnClickListener = activity;
}
Now in ViewHolder class
public void bind(final Departement item, final mOnClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
mOnClickListener.onItemClick(item);
}
});
}
and change onBindViewHolder as below
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), mOnClickListener);
}
Override onItemClick(Department item) in activity
#override
onItemClick(Department item)
{
//show toast here...
}
implement OnClickListener in your ViewHolder class
public class ViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener
{
#Override
public void onClick(View v)
{
//do action
}
}
Implement below method in your ViewHolder class.
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final User currentItem = users.get(getAdapterPosition());
Toast.makeText(mContext,currentItem.getText()+" is selected!",Toast.LENGTH_SHORT).show();
}
});

attempting to use incompatible return type

Can someone help me with this error that I keep getting? The program that I'm trying to implement admob banner ad between items in recyclerview. every thing is ok but still this one error that blocked me from go on.
public class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.ViewHolder> {
public static final String TAG = RecipeAdapter.class.getSimpleName();
public static final HashMap<String, Integer> LABEL_COLORS = new HashMap<String, Integer>() {{
put("Low-Carb", R.color.colorLowCarb);
put("Low-Fat", R.color.colorLowFat);
put("Low-Sodium", R.color.colorLowSodium);
put("Medium-Carb", R.color.colorMediumCarb);
put("Vegetarian", R.color.colorVegetarian);
put("Balanced", R.color.colorBalanced);
}};
private Context mContext;
private LayoutInflater mInflater;
private ArrayList<Recipe> mDataSource;
private static final int DEFAULT_VIEW_TYPE = 1;
private static final int NATIVE_AD_VIEW_TYPE = 2;
public RecipeAdapter(Context context, ArrayList<Recipe> items) {
mContext = context;
mDataSource = items;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); }
#Override public int getItemViewType(int position) {
// Change the position of the ad displayed here. Current is after 5
if ((position + 1) % 6 == 0) {
return NATIVE_AD_VIEW_TYPE;
}
return DEFAULT_VIEW_TYPE; }
#NonNull
#Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
switch (viewType) {
default:
view = layoutInflater
.inflate(R.layout.list_item_native_ad, parent, false);
return new ViewHolder(view);
case NATIVE_AD_VIEW_TYPE:
view = layoutInflater.inflate(R.layout.list_item_native_ad, parent, false);
return new ViewHolderAdMob(view);
}
}
#Override public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
// Get relevant subviews of row view
TextView titleTextView = holder.titleTextView;
TextView subtitleTextView = holder.subtitleTextView;
TextView detailTextView = holder.detailTextView;
ImageView thumbnailImageView = holder.thumbnailImageView;
//Get corresponding recipe for row final Recipe recipe = (Recipe) getItem(position);
// Update row view's textviews to display recipe information
titleTextView.setText(recipe.title);
subtitleTextView.setText(recipe.description);
detailTextView.setText(recipe.label);
// Use Picasso to load the image. Temporarily have a placeholder in case it's slow to load
Picasso.with(mContext).load(recipe.imageUrl).placeholder(R.mipmap
.ic_launcher).into(thumbnailImageView);
holder.parentView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent detailIntent = new Intent(mContext, RecipeDetailActivity.class);
detailIntent.putExtra("title", recipe.title);
detailIntent.putExtra("url", recipe.instructionUrl);
mContext.startActivity(detailIntent);
}
});
// Style text views
Typeface titleTypeFace = Typeface.createFromAsset(mContext.getAssets(),
"fonts/JosefinSans-Bold.ttf");
titleTextView.setTypeface(titleTypeFace);
Typeface subtitleTypeFace = Typeface.createFromAsset(mContext.getAssets(),
"fonts/JosefinSans-SemiBoldItalic.ttf");
subtitleTextView.setTypeface(subtitleTypeFace);
Typeface detailTypeFace = Typeface.createFromAsset(mContext.getAssets(),
"fonts/Quicksand-Bold.otf");
detailTextView.setTypeface(detailTypeFace);
detailTextView.setTextColor(android.support.v4.content.ContextCompat.getColor(mContext, LABEL_COLORS
.get(recipe.label)));
}
#Override public int getItemCount() {
return mDataSource.size(); }
#Override public long getItemId(int position) {
return position; }
public Object getItem(int position) {
return mDataSource.get(position); }
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView titleTextView;
private TextView subtitleTextView;
private TextView detailTextView;
private ImageView thumbnailImageView; private View parentView;
public ViewHolder(#NonNull View view){
super(view);
// create a new "Holder" with subviews
this.parentView = view;
this.thumbnailImageView = (ImageView) view.findViewById(R.id.recipe_list_thumbnail);
this.titleTextView = (TextView) view.findViewById(R.id.recipe_list_title);
this.subtitleTextView = (TextView) view.findViewById(R.id.recipe_list_subtitle);
this.detailTextView = (TextView) view.findViewById(R.id.recipe_list_detail);
// hang onto this holder for future recyclage
view.setTag(this);
}
}
public class ViewHolderAdMob extends RecyclerView.ViewHolder {
private final AdView mNativeAd;
public ViewHolderAdMob(View itemView) {
super(itemView);
mNativeAd = itemView.findViewById(R.id.nativeAd);
mNativeAd.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdLoaded");
// }
}
#Override
public void onAdClosed() {
super.onAdClosed();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdClosed");
// }
}
#Override
public void onAdFailedToLoad(int errorCode) {
super.onAdFailedToLoad(errorCode);
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdFailedToLoad");
// }
}
#Override
public void onAdLeftApplication() {
super.onAdLeftApplication();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdLeftApplication");
// }
}
#Override
public void onAdOpened() {
super.onAdOpened();
// if (mItemClickListener != null) {
Log.i("AndroidBash", "onAdOpened");
// }
}
});
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice("") // Remove this before publishing app
.build();
mNativeAd.loadAd(adRequest);
}
}
}
The return type needs to be whatever ViewHolder type you declared for your adapter class.
For example, from the Android RecyclerView example page:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
// ^^^^^^^^^^^^^^^^^^^^^^
// It should return this type ^
public static class MyViewHolder extends RecyclerView.ViewHolder {
// your adapter
}
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
// Note: returns MyAdapter.MyViewHolder, not RecyclerView.ViewHolder
}
}
In your case, you have
public class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.ViewHolder>
which means your onCreateViewHolder has to return RecipeAdapter.ViewHolder not RecyclerView.ViewHolder.
There is a separate issue too, which is that you have two ViewHolder types in the same adapter. To do this, you would need to change the ViewHolder type that your RecyclerView is based on to the generic type (RecyclerView.ViewHolder).
Please review this question, it has good answers for how to do this.

Categories

Resources