implementing "add to favourite" mechanism in RecyclerView - java

i have a recyclerView with two sections regular and Favourites and for populating my RecyclerView i have List<Object> my object class :
public class Object {
String id,channelName;
boolean isFavorite;
}
now i want to put the values which have isfavorite == true to top of my recyclerView inside my Favourite section but i don't know where to start or exactly what to do ? do i have to sort the List<Object> with booleans ? if anybody can give me a little hint or guidance then it'll be so helpful for me,
please this image for better understanding ,
this is what i'm trying to get
i added the Section in my RecyclerView by SimpleSectionedRecyclerViewAdapter

class DataModal
{
public String title;
public boolean isFavourite;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isFavourite() {
return isFavourite;
}
public void setIsFavourite(boolean isFavourite) {
this.isFavourite = isFavourite;
}
}
public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.SimpleViewHolder> {
private final Context mContext;
private List<DataModal> mData;
public void add(DataModal s,int position) {
position = position == -1 ? getItemCount() : position;
mData.add(position,s);
notifyItemInserted(position);
}
public void remove(int position){
if (position < getItemCount() ) {
mData.remove(position);
notifyItemRemoved(position);
}
}
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
public final TextView title;
public SimpleViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.simple_text);
}
}
public SimpleAdapter(Context context, ArrayList<DataModal> data) {
mContext = context;
if (data != null)
mData = data;
else mData = new ArrayList<DataModal>();
}
public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.simple_item, parent, false);
return new SimpleViewHolder(view);
}
#Override
public void onBindViewHolder(SimpleViewHolder holder, final int position) {
DataModal data = mData.get(position);
holder.title.setText(data.getTitle());
holder.title.setOnClickListener(new Listener(position,mData.get(position)));
}
class Listener implements View.OnClickListener
{
DataModal Data;
int position;
Listener(int position,DataModal Data)
{
this.Data = Data;
this.position = position;
}
#Override
public void onClick(View view) {
if(Data.isFavourite())
{
//mark the view as unfavorite
}
else{
//mark the view as favorite
}
Toast.makeText(mContext,"Position ="+position,Toast.LENGTH_SHORT).show();
}
}
#Override
public int getItemCount() {
return mData.size();
}
}

public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.SimpleViewHolder> {
private final Context mContext;
private List<String> mData;
public void add(String s,int position) {
position = position == -1 ? getItemCount() : position;
mData.add(position,s);
notifyItemInserted(position);
}
public void remove(int position){
if (position < getItemCount() ) {
mData.remove(position);
notifyItemRemoved(position);
}
}
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
public final TextView title;
public SimpleViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.simple_text);
}
}
public SimpleAdapter(Context context, String[] data) {
mContext = context;
if (data != null)
mData = new ArrayList<String>(Arrays.asList(data));
else mData = new ArrayList<String>();
}
public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.simple_item, parent, false);
return new SimpleViewHolder(view);
}
#Override
public void onBindViewHolder(SimpleViewHolder holder, final int position) {
holder.title.setText(mData.get(position));
holder.title.setOnClickListener(new Listener(position,mData.get(position),false,favview));
}
class Listener implements View.OnClickListener
{
ImageView favoriteView;
int position;
Listener(int position,String Data,boolean isFavourite,ImageView favoriteView)
{
this.favoriteView = favoriteView;
this.position = position;
}
#Override
public void onClick(View view) {
if(isFavourite)
{
//mark the view as unfavorite
}
else{
//mark the view as favorite
}
Toast.makeText(mContext,"Position ="+position,Toast.LENGTH_SHORT).show();
}
}
#Override
public int getItemCount() {
return mData.size();
}
}

Related

Cast exception on multiple viewholder recyclerview

i used multiple viewholder in DataListAdapter.
each holder have a adapter.
my adapter :
public class DataListAdapter extends BaseAdapter<HomeListItem> {
private RecyclerView.RecycledViewPool pool;
public static final int ADS = 10, DATA = 11, PIC = 13, QUE=14;
public DataListAdapter(ArrayList<HomeListItem> dataList, AdapterListener<HomeListItem> listener) {
this.dataList = dataList;
this.listener = listener;
pool = new RecyclerView.RecycledViewPool();
}
#Override
public void onViewRecycled(#NonNull BaseViewHolder holder) {
super.onViewRecycled(holder);
}
#NonNull
#Override
public BaseViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == ADS){
return new ADSDataHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_home_ads, parent, false));
}else if (viewType == PIC) {
return new PictureHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}else if (viewType == QUE) {
return new QuestionHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}else
return new DataHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}
#Override
public int getItemViewType(int position) {
if (dataList.get(position).getType() == ContentType.ADS)
return ADS;
if (dataList.get(position).getType() == ContentType.GALLERY)
return PIC;
if (dataList.get(position).getType() == ContentType.LIBS )
return DATA;
return QUE;
}
#Override
public void onBindViewHolder(#NonNull BaseViewHolder holder, int position) {
if (holder instanceof DataHolder){
((DataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof ADSDataHolder) {
((ADSDataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof PictureHolder) {
((PictureHolder) holder).bind(dataList.get(position));
}else if (holder instanceof QuestionHolder) {
((QuestionHolder) holder).bind(dataList.get(position));
}
}
class ADSDataHolder extends BaseViewHolder {
...
}
class PictureHolder extends BaseViewHolder {
...
}
class QuestionHolder extends BaseViewHolder{
private RecyclerView recyclerView;
private TextView title;
private View more;
public QuestionHolder(View itemView) {
super(itemView);
setType(QUE);
more = itemView.findViewById(R.id.more);
title = itemView.findViewById(R.id.title);
recyclerView = itemView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext(),RecyclerView.HORIZONTAL,false));
recyclerView.hasFixedSize();
recyclerView.setRecycledViewPool(pool);
}
public void bind(HomeListItem data) {
Collections.reverse(data.getData());
title.setText(data.getType().getVisibleName());
HomeQuestionAdapter adapter = new HomeQuestionAdapter((ArrayList<MainPageItem>) (ArrayList<?>) data.getData(),
new AdapterListener<MainPageItem>() {
#Override
public void onItemClick(MainPageItem item) {
onListItemClick(itemView.getContext(), data.getType(), item.getItemId());
}
});
recyclerView.setAdapter(adapter);
more.setOnClickListener(v -> listener.onItemClick(data));
}
}
class DataHolder extends BaseViewHolder {
private RecyclerView recyclerView;
private TextView title;
private View more;
DataHolder(View itemView) {
super(itemView);
setType(DATA);
more = itemView.findViewById(R.id.more);
title = itemView.findViewById(R.id.title);
recyclerView = itemView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext(),
LinearLayoutManager.HORIZONTAL, true));
recyclerView.hasFixedSize();
recyclerView.setRecycledViewPool(pool);
}
public void bind(HomeListItem data) {
Collections.reverse(data.getData());
title.setText(data.getType().getVisibleName());
SmallItemAdapter adapter = new SmallItemAdapter((ArrayList<MainPageItem>)
(ArrayList<?>) data.getData(),
new AdapterListener<MainPageItem>() {
#Override
public void onItemClick(MainPageItem item) {
onListItemClick(itemView.getContext(), data.getType(), item.getItemId());
}
});
recyclerView.setAdapter(adapter);
recyclerView.scrollToPosition(data.getData().size() - 1);
more.setOnClickListener(v -> listener.onItemClick(data));
}
}
private void onListItemClick(Context context, ContentType contentType, long id) {
// click
}
}
BaseAdapter:
public abstract class BaseAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
protected List<T> dataList;
protected final int DATA_TYPE = 1;
protected boolean isLoading = false, isMoreDataAvailable = false;
protected AdapterListener<T> listener;
#Override
public int getItemViewType(int position) {
if (dataList.get(position) == null)
return -1;
else return DATA_TYPE;
}
#Override
public int getItemCount() {
return dataList.size();
}
public void setMoreDataAvailable(boolean isMoreDataAvailable) {
this.isMoreDataAvailable = isMoreDataAvailable;
}
public void removeLoadingItem() {
if (dataList.size() > 0 && dataList.get(dataList.size() - 1) == null) {
dataList.remove(dataList.size() - 1);
notifyItemRemoved(dataList.size() - 1);
}
}
public void notifyDataChanged() {
isLoading = false;
notifyDataSetChanged();
}
}
and BaseViewHolder:
public class BaseViewHolder extends RecyclerView.ViewHolder {
private int type;
public BaseViewHolder(View itemView) {
super(itemView);
}
}
when i scroll the recyclerview gives me an error
my error:
:00:26.247 4194-4194/ir.hnfadak.shahidezendeh E/PushPole:Exception caught
java.lang.ClassCastException: ir.hfadak.fadakmedia.UI.Main.Home.Picture.SmallItemAdapter$DataHolder cannot be cast to ir.hfadak.fadakmedia.UI.Main.Question.HomeQuestionAdapter$DataQueHolder
at ir.hfadak.fadakmedia.UI.Main.Question.HomeQuestionAdapter.onBindViewHolder(HomeQuestionAdapter.java:31)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6238)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
and my HomeQuestionAdapter
public class HomeQuestionAdapter extends RecyclerView.Adapter<HomeQuestionAdapter.DataQueHolder> {
private RoundedCorners roundedCorners;
protected List<MainPageItem> dataList;
protected final int DATA_TYPE = 1;
protected boolean isLoading = false, isMoreDataAvailable = false;
protected AdapterListener<MainPageItem> listener;
public HomeQuestionAdapter(ArrayList<MainPageItem> dataList, AdapterListener<MainPageItem> listener) {
this.dataList = dataList;
this.listener = listener;
roundedCorners = new RoundedCorners(16);
}
#Override
public int getItemViewType(int position) {
if (dataList.get(position) == null)
return -1;
else return DATA_TYPE;
}
#Override
public int getItemCount() {
return dataList.size();
}
public void setMoreDataAvailable(boolean isMoreDataAvailable) {
this.isMoreDataAvailable = isMoreDataAvailable;
}
public void removeLoadingItem() {
if (dataList.size() > 0 && dataList.get(dataList.size() - 1) == null) {
dataList.remove(dataList.size() - 1);
notifyItemRemoved(dataList.size() - 1);
}
}
public void notifyDataChanged() {
isLoading = false;
notifyDataSetChanged();
}
#NonNull
#Override
public HomeQuestionAdapter.DataQueHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new DataQueHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_simple_question, parent, false));
}
#Override
public void onBindViewHolder(#NonNull HomeQuestionAdapter.DataQueHolder holder, int position) {
if (!isLoading && isMoreDataAvailable && position >= getItemCount() - 1) {
isLoading = true;
listener.onLoadMore();
} else {
holder.bind(dataList.get(position));
}
}
class DataQueHolder extends RecyclerView.ViewHolder {
private ImageView image;
private ImageView share,faivorid;
private TextView question,answer,view;
DataQueHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.imageQue);
question = itemView.findViewById(R.id.titleQue);
answer = itemView.findViewById(R.id.answerQue);
share = itemView.findViewById(R.id.share);
faivorid = itemView.findViewById(R.id.favorite);
view = itemView.findViewById(R.id.viewtxt);
}
void bind(MainPageItem data) {
Glide.with(itemView)
.load(data.getItemSmallImageAddress())
.apply(bitmapTransform(roundedCorners))
.apply(new RequestOptions().error(R.drawable.img_list_def)
.placeholder(R.drawable.img_list_def))
.into(image);
question.setText(data.getItemTitle());
answer.setText(data.getItemDescription());
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ContextUtil.share(itemView.getContext(),
data.getItemTitle() + "\n\n"
+ data.getItemDescription() + "\n\n"
+ data.getItemSmallImageAddress());
}
});
itemView.setOnClickListener(v -> listener.onItemClick(data));
}
}
}
Where does the code is wrong?
Your are type casting instance of super class to a reference of sub class which is causing this error.
Instead create something like this:-
public void onBindViewHolder(#NonNull BaseViewHolder holder, int position) {
if (holder instanceof DataQueHolder){
((DataQueHolder) holder).bind(dataList.get(position));
}else if (holder instanceof DataHolder){
((DataHolder) holder).bind(dataList.get(position));
}else if (holder instanceof ADSDataHolder) {
((ADSDataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof PictureHolder) {
((PictureHolder) holder).bind(dataList.get(position));
}else if (holder instanceof QuestionHolder) {
((QuestionHolder) holder).bind(dataList.get(position));
}
}
Please remove this below line from DataListAdapter
recyclerView.setRecycledViewPool(pool);
It works for me..

how can fillter the recyclerView

how can i filter Recycler View using SearchView
i try all the video tuturial but all of them get thier item Recycler View from a list
but i get my item from db and dont know how should i do this
this is my adapter Code
public class AthleteAdapter extends RecyclerView.Adapter<AthleteAdapter.AthleteHolder> {
private List<Athlete> athletes = new ArrayList<>();
private OnItemClickListener listener;
#NonNull
#Override
public AthleteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemview = LayoutInflater.from(parent.getContext()).inflate(R.layout.athlete_item, parent, false);
return new AthleteHolder(itemview);
}
#Override
public void onBindViewHolder(#NonNull AthleteHolder holder, int position) {
Athlete currnetAthlete = athletes.get(position);
holder.textViewName.setText(currnetAthlete.getAthlete_name());
holder.textViewLastname.setText(currnetAthlete.getAthlete_lastname());
holder.textView_phonenumber.setText(currnetAthlete.getAthlete_phonenumber());
holder.textViewTime1.setText(String.valueOf(currnetAthlete.getSign_in_time()));
holder.textViewTime2.setText(String.valueOf(currnetAthlete.getCheck_tution_time()));
}
public void setAthletes(List<Athlete> athletes) {
this.athletes = athletes;
notifyDataSetChanged();
}
public Athlete getposition(int position) {
return athletes.get(position);
}
#Override
public int getItemCount() {
return athletes.size();
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public interface OnItemClickListener {
void onItemClick(Athlete athlete);
}
class AthleteHolder extends RecyclerView.ViewHolder {
private TextView textViewName, textViewLastname, textView_phonenumber, textViewTime1, textViewTime2;
public AthleteHolder(#NonNull View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.name_main);
textViewLastname = itemView.findViewById(R.id.lastname_main);
textView_phonenumber = itemView.findViewById(R.id.textView_number);
textViewTime1 = itemView.findViewById(R.id.time1);
textViewTime2 = itemView.findViewById(R.id.time2);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION) {
listener.onItemClick(athletes.get(position));
}
}
});
}
}
}
Step 1 : Get all data from db and give that list to Adapter
usersList = db.getAll();
adapter = new dataAdapter(getApplicationContext(), usersList);
adapter.setdatainterfacemethod(this);
Step 2 : get Text from Searchview
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
filter(s.toString());
}
return false;
}
});
Step 3 : compare searchview text and list text if exits then give list to adapter
public void filter(String text) {
List<Users> name = new ArrayList<>();
for (Users u : usersList) {
if (u.getNAME().toLowerCase().contains(text.toLowerCase())) {
name.add(u);
}
}
adapter.filterlist(name);
}
Step 4 :- change list and notify adapter (in adapter class)
public void filterlist(List<Users> name) {
this.usersList = name;
notifyDataSetChanged();
}
--------------------- Adapter class -----------------
public class dataAdapter extends RecyclerView.Adapter<dataAdapter.viewholder> {
public List<Users> usersList;
Context context;
dataInterface dataInterface;
public dataAdapter(Context context, List<Users> usersList) {
this.usersList = usersList;
this.context = context;
}
public void setdatainterfacemethod(dataInterface dataInterface) {
this.dataInterface = dataInterface;
}
#NonNull
#Override
public viewholder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.include_recycle_demo, viewGroup, false);
return new viewholder(view);
}
#Override
public void onBindViewHolder(#NonNull final viewholder viewholder, final int i) {
}
#Override
public int getItemCount() {
return usersList.size();
}
public void filterlist(List<Users> name) {
this.usersList = name;
notifyDataSetChanged();
}
public class viewholder extends RecyclerView.ViewHolder {
public viewholder(#NonNull View itemView) {
super(itemView);
}
}
}

Recycle view adapter how i highlighted single item on click

I'm using recycler view and I implement this functionality as per project requirement. But in my case item is highlighted but not unhighlighted again.
I was confused where I click the item for creating the clicking functionality, and how to unhighlighted the item. Please suggest me the right way to solve the code
public class LoadVehicleTypeAdapter extends RecyclerView.Adapter<LoadVehicleTypeAdapter.CarTypesHolder> {
private List<TaxiTypeResponse.Message> CarTypesModelsList;
private Context mContext;
VehicleTypeView vehicleTypeView;
setOnitemclick listener;
private SparseBooleanArray selectedItems = new SparseBooleanArray();
int I=-1;
public class CarTypesHolder extends RecyclerView.ViewHolder {
public CustomTextView mCarType;
public CircleImageView mCarTypeImage;
LinearLayout llRoot;
CardView cardView;
private SparseBooleanArray selectedItems = new SparseBooleanArray();
setOnitemclick listener;
public CarTypesHolder(final View view) {
super(view);
mCarType = (CustomTextView) view.findViewById(R.id.frag_cartypes_inflated_name);
mCarTypeImage = (CircleImageView) view.findViewById(R.id.frag_cartype_inflated_frameImage);
llRoot = (LinearLayout)view.findViewById(R.id.root1);
cardView=(CardView) view.findViewById(R.id.cardf);
}
public void setOnItemClickListner(setOnitemclick listener12) {
listener=listener12;
}
}
public void setOnItemClickListner(setOnitemclick listener12) {
listener=listener12;
}
public LoadVehicleTypeAdapter(Context context, List<TaxiTypeResponse.Message> CarTypesModelsList, VehicleTypeView vehicleTypeView) {
this.CarTypesModelsList = CarTypesModelsList;
mContext = context;
this.vehicleTypeView = vehicleTypeView;
}
#Override
public CarTypesHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.frag_cartype_inflated_view, parent, false);
return new CarTypesHolder(itemView);
}
#SuppressLint("ResourceType")
#Override
public void onBindViewHolder(final CarTypesHolder holder, final int position) {
TaxiTypeResponse.Message carTypesModel = CarTypesModelsList.get(position);
I=CarTypesModelsList.get(position).getID();
holder.mCarType.setText(carTypesModel.getName());
holder.mCarTypeImage.setBackgroundResource(R.drawable.wait);
int color = Color.parseColor(PreferenceHandler.readString(mContext,PreferenceHandler.SECONDRY_COLOR,"#006fb6"));
holder.llRoot.setSelected(selectedItems.get(position, false));
holder.mCarType.setTextColor(color);
holder.setOnItemClickListner(listener);
holder. llRoot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
I=position;
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
notifyDataSetChanged();
}
});
if (I==position)
{
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
}
else
{
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#999999"));
}
Picasso.with(mContext).load(carTypesModel.getImagePath()).into(holder.mCarTypeImage);
}
#Override
public long getItemId(int position) {
return CarTypesModelsList.get(position).getID();
}
#Override
public int getItemCount() {
return CarTypesModelsList.size();
}
public void setSelection(LinearLayout imageView,CustomTextView textView,boolean value,int position){
if(value){
imageView.setBackgroundColor(Color.parseColor("#999999"));
textView.setTextColor(Color.parseColor("#FFFFFF"));
}else{
System.out.println("11111111111111111000000111111111111");
imageView.setBackgroundColor(Color.parseColor("#f3f3f3"));
textView.setTextColor(Color.parseColor("#2196F3"));
}
}
public interface setOnitemclick{
void ImageClick(int position, String Name,String Description,int id);
void ImageClickfade(int position, String Name,String Description,int id);
}
#Override
public int getItemViewType(int position) {
return position;
}
}
I'll use to update gradle
maven { url "https://maven.google.com" }
and update the code
public class LoadVehicleTypeAdapter extends RecyclerView.Adapter<LoadVehicleTypeAdapter.CarTypesHolder> {
private List<TaxiTypeResponse.Message> CarTypesModelsList;
private Context mContext;
VehicleTypeView vehicleTypeView;
int I=-1;
public class CarTypesHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CustomTextView mCarType;
public CircleImageView mCarTypeImage;
LinearLayout llRoot;
CardView cardView;
setOnitemclick listener;
public void setOnItemClickListner(setOnitemclick listener)
{
this.listener=listener;
}
public CarTypesHolder(View view) {
super(view);
mCarType = (CustomTextView) view.findViewById(R.id.frag_cartypes_inflated_name);
mCarTypeImage = (CircleImageView) view.findViewById(R.id.frag_cartype_inflated_frameImage);
llRoot = (LinearLayout)view.findViewById(R.id.root1);
cardView=(CardView) view.findViewById(R.id.cardf);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
listener.ImageClick(v,getAdapterPosition());
}
}
public LoadVehicleTypeAdapter(Context context, List<TaxiTypeResponse.Message> CarTypesModelsList, VehicleTypeView vehicleTypeView) {
this.CarTypesModelsList = CarTypesModelsList;
mContext = context;
this.vehicleTypeView = vehicleTypeView;
}
#Override
public CarTypesHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.frag_cartype_inflated_view, parent, false);
return new CarTypesHolder(itemView);
}
#SuppressLint("ResourceType")
#Override
public void onBindViewHolder( final CarTypesHolder holder, int position) {
TaxiTypeResponse.Message carTypesModel = CarTypesModelsList.get(position);
holder.mCarType.setText(carTypesModel.getName());
holder.mCarTypeImage.setBackgroundResource(R.drawable.wait);
int color = Color.parseColor(PreferenceHandler.readString(mContext,PreferenceHandler.SECONDRY_COLOR,"#006fb6"));
holder.mCarType.setTextColor(color);
holder.setOnItemClickListner(new setOnitemclick() {
#Override
public void ImageClick(View v,int position1) {
I=position1;
notifyDataSetChanged();
System.out.println("11100011111");
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
}
});
if (I==position)
{
System.out.println("11100011111....");
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
}
else
{
System.out.println("11100011111----");
holder.llRoot.setBackgroundColor(Color.parseColor("#f3f3f3"));
holder.mCarType.setTextColor(Color.parseColor("#2196F3"));
}
Picasso.with(mContext).load(carTypesModel.getImagePath()).into(holder.mCarTypeImage);
}
#Override
public long getItemId(int position) {
return CarTypesModelsList.get(position).getID();
}
#Override
public int getItemCount() {
return CarTypesModelsList.size();
}
public void setSelection(LinearLayout imageView,CustomTextView textView,boolean value,int position){
if(value){
imageView.setBackgroundColor(Color.parseColor("#999999"));
textView.setTextColor(Color.parseColor("#FFFFFF"));
}else{
System.out.println("11111111111111111000000111111111111");
imageView.setBackgroundColor(Color.parseColor("#f3f3f3"));
textView.setTextColor(Color.parseColor("#2196F3"));
}
}
public interface setOnitemclick{
void ImageClick(View view,int position);
}
#Override
public int getItemViewType(int position) {
return position;
}
}

onClickListener in RecyclerView.ViewHolder

I've got a RecyclerView.ViewHolder and RecyclerView.Adapter, I need after click on item and then send information about this item to another Activity.
PlacesAdapter.java
public class PlacesAdapter extends RecyclerView.Adapter<PlacesViewHolder> {
private PlacesActivity placesActivity;
Context context;
private int position;
List<Places> places;
public PlacesAdapter(List<Places> places) {
this.places = places;}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public PlacesViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.places_view, viewGroup, false);
PlacesViewHolder pvh = new PlacesViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(PlacesViewHolder personViewHolder, int i) {
personViewHolder.name.setText(places.get(i).name);
personViewHolder.address.setText(places.get(i).address);
Picasso.with(personViewHolder.itemView.getContext())
.load(places.get(i).photo)
.into(personViewHolder.getPhoto());
}
#Override
public int getItemCount() {
return places.size();
}
}
PlacesViewHolder.java
In this line "intent.putExtra(PlacesDetail.PLACES_NAME,);" How can I send name?
public class PlacesViewHolder extends RecyclerView.ViewHolder {
CardView cv;
public TextView name;
public TextView address;
public ImageView photo;
public PlacesViewHolder(final View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
name = (TextView)itemView.findViewById(R.id.person_name);
address = (TextView)itemView.findViewById(R.id.person_age);
photo = (ImageView)itemView.findViewById(R.id.person_photo);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, PlacesDetail.class);
intent.putExtra(PlacesDetail.PLACES_NAME,);
context.startActivity(intent);
}
});
}
public TextView getAddress() {
return address;
}
public TextView getName() {
return name;
}
public ImageView getPhoto() {
return photo;
}
}
This is the complete example of custom Adapter where i'm able to get the details of particular items. In MainActivity you need to set the adapter :
adapter = new MyAdapter(getApplicationContext(), account_no, title, aFN1, aLN1,aFN2, aLN2,aFN3, aLN3,isavilable,waitlist,flag);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
Now see the code for the custom Adapter :
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
String TAG = "MyAdapter";
Context context;
private String[] accountNo;
private String[] title;
private String[] afn1;
private String[] aln1;
private String[] afn2;
private String[] aln2;
private String[] afn3;
private String[] aln3;
private String[] isAvailable;
private String[] waitlist;
private int flag;
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView account_no,title,afn1,afn2,aln1,aln2,color,is_available;
private ImageView img_android;
CardView cardView;
public ViewHolder(CardView v) {
super(v);
account_no = (TextView)v.findViewById(R.id.acctno);
title = (TextView)v.findViewById(R.id.title);
afn1 = (TextView) v.findViewById(R.id.afn1);
cardView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(Context context, String[] accountNo,String[] title,String[] afn1,String[] aln1,String[] afn2,String[] aln2,String[] afn3,String[] aln3,String[] isAvailable, String[] waitlist,int flag) {
this.context = context;
this.accountNo = accountNo;
this.title = title;
this.afn1 = afn1;
this.aln1 = aln1;
this.afn2 = afn2;
this.aln2 = aln2;
this.afn3 = afn3;
this.aln3 = aln3;
this.isAvailable = isAvailable;
this.waitlist = waitlist;
this.flag = flag;
Log.d(TAG,afn1.toString() +aln1+afn2+aln2+afn3+aln3.toString()+waitlist);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
CardView cv = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(cv);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final CardView cardView = holder.cardView;
final TextView accountno = (TextView)cardView.findViewById(R.id.acctno);
accountno.setText(accountNo[position]);
final TextView titletxt = (TextView)cardView.findViewById(R.id.title);
titletxt.setText(title[position]);
final TextView afn1txt = (TextView) cardView.findViewById(R.id.afn1);
afn1txt.setText(afn1[position]+" "+aln1[position]);
Log.d(TAG,waitlist[position]);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = getItemViewType(position);
SharedPreferences sharedPreferences = context.getSharedPreferences(Constant.MYPREFERENCE,Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.putString(Constant.ACCOUNT,accountNo[position]);
edit.putString(Constant.TITLE,title[position]);
edit.putString(Constant.AFN1,afn1[position]);
edit.putString(Constant.ALN1,aln1[position]);
edit.putString(Constant.AFN2,afn2[position]);
edit.putString(Constant.ALN2,aln2[position]);
edit.putString(Constant.AFN3,afn3[position]);
edit.putString(Constant.ALN3,aln3[position]);
edit.putBoolean(Constant.IS_AVAILABLE, Boolean.parseBoolean(isAvailable[position].toUpperCase()));
edit.putString(Constant.WAITLIST,waitlist[position]);
Log.d("WaitingNo2 :",""+String.valueOf(waitlist[position]));
edit.commit();
Intent intent = new Intent(v.getContext(), DetailsActivity.class);
v.getContext().startActivity(intent);
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return accountNo.length;
}
}
After All that get the value from sharedPreferences in the Activity which is called on Card Click:
preferences = getSharedPreferences("myshared", Context.MODE_PRIVATE);
AccountNo = sharedPreferences.getString(Constant.ACCOUNT,null).toUpperCase();
title = sharedPreferences.getString(Constant.TITLE,null).toUpperCase();
afn1 = sharedPreferences.getString(Constant.AFN1,null).toUpperCase();
aln1 = sharedPreferences.getString(Constant.ALN1,null).toUpperCase();
afn2 = sharedPreferences.getString(Constant.AFN2,null).toUpperCase();
aln2 = sharedPreferences.getString(Constant.ALN2,null).toUpperCase();
afn3 = sharedPreferences.getString(Constant.AFN3,null).toUpperCase();
aln3 = sharedPreferences.getString(Constant.ALN3,null).toUpperCase();
isAvailable = sharedPreferences.getBoolean(Constant.IS_AVAILABLE,isAvailable);
waitlist = sharedPreferences.getString(Constant.WAITLIST,waitlist);
Now do whatever you want and enjoy the code.
You can achieve this by creating an interface inside your adapter for an itemclicklistener and then you can set onItemClickListener from your PlacesActivity.
Somewhere inside your PlacesAdapter you would need the following:
private onRecyclerViewItemClickListener mItemClickListener;
public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public interface onRecyclerViewItemClickListener {
void onItemClickListener(View view, int position, String places_name);
}
Then inside your ViewHolder (which I've added as an inner class inside my adapter), you would apply the listener to the components you'd like the user to click, like so:
class PlacesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
PlacesViewHolder(View view) {
super(view);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClickListener(v, getAdapterPosition(), PlacesDetail.PLACES_NAME);
}
}
}
This example shows an onClickListener being applied to the view inside PlacesViewHolder.
recyclerView.setAdapter(adapter);// set adapter on recyclerview
adapter.notifyDataSetChanged();// Notify the adapter
adapter.setOnItemClickListener(new PlacesAdapter.onRecyclerViewItemClickListener() {
#Override
public void onItemClickListener(View view, int position, String places_name) {
//perform click logic here (places_name is passed)
}
});
To implement this code, you would setOnItemClickListener to your adapter inside PlacesActivity as shown above.
try this , it's work with me correctly
Create a new class and this code
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
#Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
#Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
#Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
And in your Activity add this to your adapter implementation
mRecyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), mRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
// do something
}
}
}
#Override
public void onLongItemClick(View view, int position) {
// do whatever
}
})
);

How to use one RecyclerView adapter for objects of different types using generics?

I have a RecyclerView which I want to be populated with String objects sometimes & with Product objects some other time. So I started creating its manager adapter this way:
// BaseSearchAdapter is the class that contains the 'List<T> mItems' member variable
public class SearchAdapter<T> extends BaseSearchAdapter<SearchAdapter.ViewHolder, T> {
private Context mContext;
public SearchAdapter(Context context, List<T> items) {
mContext = context;
mItems = new ArrayList<>(items);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
T item = mItems.get(position);
holder.bind(item);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textLabel;
public ViewHolder(View v) {
}
public void bind(T item) {
textLabel.setText(...); // How to handle T ?
}
}
}
where T could be String or Product according to the plan.
My question is how can I appropriately bind the data (whether it's a String or a Product) object to its corresponding view in this situation? Or is there a better way to handle this ?
// BaseSearchAdapter is the class that contains the 'List<T> mItems' member variable
public class SearchAdapter<T> extends BaseSearchAdapter<SearchAdapter.ViewHolder<T>, T> {
private Context mContext;
private ViewHolderBinder<T> mBinder;
public SearchAdapter(Context context, List<T> items, ViewHolderBinder<T> binder) {
mContext = context;
mItems = new ArrayList<>(items);
mBinder = binder;
}
#Override
public void onBindViewHolder(ViewHolder<T> holder, int position) {
T item = mItems.get(position);
holder.bind(item);
}
public static class ViewHolder<T> extends RecyclerView.ViewHolder {
ViewHolderBinder<T> mBinder;
TextView textLabel;
public ViewHolder(View v, ViewHolderBinder<T> binder) {
textLabel = (TextView)v.findViewById(R.id.text_label);
this.mBinder = binder;
}
public void bind(T item) {
binder.bind(this, item);
}
}
public interface ViewHolderBinder<T> {
void bind(ViewHolder<T> viewHolder, T item);
}
public static class StringViewHolderBinder implements ViewHolderBinder<String> {
#Override
public void bind(ViewHolder<String> viewHolder, String item) {
viewHolder.textLabel.setText(item);
}
}
public static class ProductViewHolderBinder implements ViewHolderBinder<Product> {
#Override
public void bind(ViewHolder<Product> viewHolder, Product item) {
viewHolder.textLabel.setText(item.getName());
}
}
}
What I do on my projects is create a class BaseRecyclerAdapter that has all of my common operations. Then for most adapters all I have to define is the ViewHolder and the layout.
UPDATE
As Requested I posted a fuller version of my BaseRecyclerAdapter (it varies a bit based upon project need). Also include is a simple gesture callback that allows you to easily enable swipe to remove or drag to reorder operations.
NOTE: This version updates how the recycler item layouts are inflated. I now prefer to inflate the in the BaseRecyclerAdapter.ViewHolder constructor allowing the layout to be specified in the extending ViewHolder's constructor.
Example Base Adapter
public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<BaseRecyclerAdapter.ViewHolder> {
private final List<T> items = new ArrayList<>();
OnItemSelectedListener<T> onItemSelectedListener = SmartNull.create(OnItemSelectedListener.class);
public BaseRecyclerAdapter setOnItemSelectedListener(OnItemSelectedListener<T> onItemSelectedListener) {
if (onItemSelectedListener == null) {
this.onItemSelectedListener = SmartNull.create(OnItemSelectedListener.class);
} else {
this.onItemSelectedListener = onItemSelectedListener;
}
return this;
}
public boolean isEmpty() {
return items.isEmpty();
}
public void setItems(List<T> items) {
this.items.clear();
this.items.addAll(items);
notifyDataSetChanged();
}
public void addItems(T... items) {
addItems(Arrays.asList(items));
}
public void addItems(List<T> items) {
int startPosition = this.items.size() - 1;
this.items.addAll(items);
notifyItemRangeInserted(startPosition, items.size());
}
public void removeItem(int position) {
T item = items.remove(position);
if (itemRemovedListener != null) {
itemRemovedListener.onItemRemoved(item);
}
notifyItemRemoved(position);
}
public void removeItem(T t) {
int index = items.indexOf(t);
if (index >= 0) {
removeItem(index);
}
}
public void addItem(T item) {
items.add(item);
notifyItemInserted(getItemCount() - 1);
}
public void moveItem(int startPosition, int targetPosition) {
if (startPosition < targetPosition) {
for (int i = startPosition; i < targetPosition; i++) {
Collections.swap(items, i, i + 1);
}
} else {
for (int i = startPosition; i > targetPosition; i--) {
Collections.swap(items, i, i - 1);
}
}
notifyItemMoved(startPosition, targetPosition);
}
public List<T> getItems() {
return new ArrayList<>(items);
}
public void setItemAt(int position, T item){
items.set(position, item);
notifyItemChanged(position);
}
public void refreshItem(T item) {
int i = items.indexOf(item);
if (i >= 0) {
notifyItemChanged(i);
}
}
protected void setItemWithoutUpdate(int position, T item){
items.set(position, item);
}
public int indexOf(T t) {
return items.indexOf(t);
}
#SuppressWarnings("unchecked")
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bindItemAt(getItemAt(position), position);
}
#Override
public int getItemCount() {
return items.size();
}
public T getItemAt(int position) {
return items.get(position);
}
private void onItemSelected(int position) {
if (isValidPosition(position)) {
onItemSelectedListener.onItemSelected(getItemAt(position));
}
}
boolean isValidPosition(int position) {
return position >=0 && position < items.size();
}
public abstract class ViewHolder<T> extends RecyclerView.ViewHolder implements View.OnClickListener {
public ViewHolder(ViewGroup parent, #LayoutRes int layoutId) {
super(LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false));
itemView.setOnClickListener(this);
}
public ViewHolder(View view) {
super(view);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onItemSelected(getAdapterPosition());
}
public abstract void bindItemAt(T t, int position);
}
public interface OnItemSelectedListener<T> {
void onItemSelected(T t);
}
}
Example Implementation
public class ExampleAdapter extends com.stratospherequality.mobileworkforce.modules.common.BaseRecyclerAdapter<Long> {
#Override
protected RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(parent);
}
private class ViewHolder extends RecyclerViewHolder<Long> {
TextView text;
public ViewHolder(ViewGroup parent) {
super(parent, R.layout.row_my_layout);
// I typically use ButterKnife here but this works as well
text = (TextView) itemView.findViewById(R.id.text);
}
#Override
public void setItem(Long value, int position) {
text.setText("#" + value);
}
}
}
Base GestureCallback
public class AdapterGestureCallback extends ItemTouchHelper.SimpleCallback {
public interface OnRemoveItemCallback<T> {
void onRemoveItem(BaseRecyclerAdapter<T> adapter, T t);
}
public enum Direction {
UP(ItemTouchHelper.UP),
DOWN(ItemTouchHelper.DOWN),
LEFT(ItemTouchHelper.LEFT),
RIGHT(ItemTouchHelper.RIGHT),
START(ItemTouchHelper.START),
END(ItemTouchHelper.END);
public final int value;
Direction(int value) {
this.value = value;
}
}
private final BaseRecyclerAdapter adapter;
private OnRemoveItemCallback onRemoveItemCallback;
private boolean enabled = true;
public AdapterGestureCallback(BaseRecyclerAdapter adapter) {
super(0, 0);
this.adapter = adapter;
}
public AdapterGestureCallback setOnRemoveItemCallback(OnRemoveItemCallback onRemoveItemCallback) {
this.onRemoveItemCallback = onRemoveItemCallback;
return this;
}
public AdapterGestureCallback setEnabled(boolean enabled) {
this.enabled = enabled;
return this;
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
adapter.moveItem(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
if (onRemoveItemCallback == null){
adapter.removeItem(position);
} else {
onRemoveItemCallback.onRemoveItem(adapter, adapter.getItemAt(position));
}
}
public AdapterGestureCallback withDragDirections(Direction... dragDirections) {
setDefaultDragDirs(valueFor(dragDirections));
return this;
}
public AdapterGestureCallback withSwipeDirections(Direction... swipeDirections) {
setDefaultSwipeDirs(valueFor(swipeDirections));
return this;
}
#Override
public boolean isItemViewSwipeEnabled() {
return enabled;
}
#Override
public boolean isLongPressDragEnabled() {
return enabled;
}
public int valueFor(Direction... directions) {
int val = 0;
for (Direction d : directions) {
val |= d.value;
}
return val;
}
public AdapterGestureCallback attach(RecyclerView recyclerView) {
new ItemTouchHelper(this).attachToRecyclerView(recyclerView);
return this;
}
}
GestureCallback with swiping
new AdapterGestureCallback(adapter)
.withSwipeDirections(AdapterGestureCallback.Direction.LEFT, AdapterGestureCallback.Direction.RIGHT)
.setOnRemoveItemCallback(this)
.attach(recyclerView);
Can use generic for Holder like this:
public abstract class ActionBarAdapter<T,VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private Context mContext;
public SearchAdapter(Context context, List<T> items) {
mContext = context;
mItems = new ArrayList<>(items);
}
}
The approach that, for example, ArrayAdapter<T> uses is to call toString() on whatever T you pass. This will of course work for a String, and you'll have to implement toString() in your Product to return a meaningful representation.

Categories