Is it possible to call same adapter in two activity for different different work
Here is my RecyclerAdapter:
Only difference when calling from two activity is in this line: From Activity1.java it is:
holder.Name.setText(arrayList.get(position).getName());
And from Activity2.java
holder.Name.setText(arrayList.get(position).getVehicle());
All other code is same how can I use same adapter for different different work.
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private ArrayList<Contact> arrayList= new ArrayList<>();
public RecyclerAdapter(ArrayList<Contact> arrayList){
this.arrayList= arrayList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder (MyViewHolder holder, int position) {
holder.Name.setText(arrayList.get(position).getName());
int sync_status = arrayList.get(position).getSync_status();
if(sync_status== DbContact.SYNC_STATUS_OK){
holder.Sync_Status.setImageResource(R.drawable.success);
}
else {
holder.Sync_Status.setImageResource(R.drawable.stopwatch);
}
}
#Override
public int getItemCount() {
return arrayList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
ImageView Sync_Status;
TextView Name;
public MyViewHolder(View itemView) {
super(itemView);
Sync_Status=(ImageView)itemView.findViewById(R.id.imgSync);
Name=(TextView)itemView.findViewById(R.id.txtName);
}
}
}
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private ArrayList<Contact> arrayList= new ArrayList<>();
private int whichActivity;
public RecyclerAdapter(ArrayList<Contact> arrayList, int activity){
whichActivity = activity;
this.arrayList= arrayList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder (MyViewHolder holder, int position) {
if(whichActivity == 0) {
holder.Name.setText(arrayList.get(position).getName());
}
else {
holder.Name.setText(arrayList.get(position).getVehicle());
}
int sync_status = arrayList.get(position).getSync_status();
if(sync_status== DbContact.SYNC_STATUS_OK){
holder.Sync_Status.setImageResource(R.drawable.success);
}
else {
holder.Sync_Status.setImageResource(R.drawable.stopwatch);
}
}
#Override
public int getItemCount() {
return arrayList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
ImageView Sync_Status;
TextView Name;
public MyViewHolder(View itemView) {
super(itemView);
Sync_Status=(ImageView)itemView.findViewById(R.id.imgSync);
Name=(TextView)itemView.findViewById(R.id.txtName);
}
}
}
Try this code. Now when you create your RecyclerAdapter in Activity1 call new RecyclerAdapter(arrayList, 0) and when you create your RecyclerAdapter in Activity2 call new RecyclerAdapter(arrayList, 1). You are just passing a variable into the constructor so your adapter knows which activity it is in and can run through different logic depending on the activity.
Related
I have an adapter that is showing limited Items on Fragment.
#Override
public int getItemCount() {
int limit = 7;
return Math.min(latestProductModelList.size(),limit);
}
and I want to show all the items of list in recyclerview when I click on ViewAll button using the same adapter on another acitivity.
this is my adapter.
`
public class LatestProductAdapter extends RecyclerView.Adapter<LatestProductAdapter.ViewHolder> {
List<LatestProductModel> latestProductModelList = new ArrayList<>();
Context context;
LatestProductClickInterface latestProductClickInterface;
public LatestProductAdapter(Context context, LatestProductClickInterface latestProductClickInterface) {
this.context = context;
this.latestProductClickInterface = latestProductClickInterface;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_layout,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
LatestProductModel latestProductModel = latestProductModelList.get(position);
Glide.with(context).load(latestProductModel.getImage()).into(holder.itemImage);
holder.itemTitle.setText(latestProductModel.getTitle());
holder.itemView.setOnClickListener(v -> {
latestProductClickInterface.OnLatestProductClicked(latestProductModelList.get(position));
});
}
#Override
public int getItemCount() {
int limit = 7;
return Math.min(latestProductModelList.size(),limit);
}
#SuppressLint("NotifyDataSetChanged")
public void updateList(List<LatestProductModel> latestProductModels){
latestProductModelList.clear();
latestProductModelList.addAll(latestProductModels);
Collections.reverse(latestProductModelList);
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView itemImage;
TextView itemTitle;
public ViewHolder(#NonNull View itemView) {
super(itemView);
itemImage = itemView.findViewById(R.id.item_img);
itemTitle = itemView.findViewById(R.id.item_title);
}
}
}
`
How to achieve this?
Or is there another way to achieve this?
kindly help me.
You can use bellow codes for your adapter:
public class LatestProductAdapter extends RecyclerView.Adapter<LatestProductAdapter.ViewHolder> {
List<LatestProductModel> latestProductModelList = new ArrayList<>();
Context context;
LatestProductClickInterface latestProductClickInterface;
private boolean shouldShowAllItems;
public LatestProductAdapter(Context context, LatestProductClickInterface latestProductClickInterface , boolean shouldShowAllItems) {
this.context = context;
this.latestProductClickInterface = latestProductClickInterface;
this.shouldShowAllItems = shouldShowAllItems;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_layout,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
LatestProductModel latestProductModel = latestProductModelList.get(position);
Glide.with(context).load(latestProductModel.getImage()).into(holder.itemImage);
holder.itemTitle.setText(latestProductModel.getTitle());
holder.itemView.setOnClickListener(v -> {
latestProductClickInterface.OnLatestProductClicked(latestProductModelList.get(position));
});
}
#Override
public int getItemCount() {
if (shouldShowAllItems){
return latestProductModelList.size();
}else {
int limit = 7;
return Math.min(latestProductModelList.size(), limit);
}
}
#SuppressLint("NotifyDataSetChanged")
public void updateList(List<LatestProductModel> latestProductModels){
latestProductModelList.clear();
latestProductModelList.addAll(latestProductModels);
Collections.reverse(latestProductModelList);
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView itemImage;
TextView itemTitle;
public ViewHolder(#NonNull View itemView) {
super(itemView);
itemImage = itemView.findViewById(R.id.item_img);
itemTitle = itemView.findViewById(R.id.item_title);
}
}
}
and create adapter object accourding your need:
LatestProductAdapter latestProductAdapter = LatestProductAdapter(context , this ,//true or false);
I tried to create a RecycleView for more Objects to display but for some reason funcion getItemViewType doesnt work or it might work but selects second option only because the output from onCreateViewHolder is always the first option.
This is the funcion in the method
private void insertObjects(){
items.add(new Object(1));
items.add(new Object(2));
mMultiAdapter.notifyDataSetChanged();
This is the Adapter
Even if I change first if of getItemViewType to if(position % 2 == 0) > it will output the same option everytime
public class MultiAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public MultiAdapter(List<Object> Parts) { this.items = Parts; }
public static class ChestViewHolder extends RecyclerView.ViewHolder{
TextView second_segment;
private ChestViewHolder( View itemView) {
super(itemView);
second_segment = itemView.findViewById(R.id.segment_tuesday);
}
public static class BackViewHolder extends RecyclerView.ViewHolder {
TextView first_segment;
private BackViewHolder( View itemView) {
super(itemView);
first_segment = itemView.findViewById(R.id.segment_monday);
}
public static class DefaultViewHolder extends RecyclerView.ViewHolder {
TextView default_segment;
private DefaultViewHolder( View itemView) {
super(itemView);
default_segment = itemView.findViewById(R.id.segment_sunday);
}
}
private static int ITEM_TYPE_C_T;
private static int ITEM_TYPE_S_B;
private List<Object> items = new ArrayList<>();
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder Holder, int position) {non code inside of this method}
#Override
public int getItemViewType(int position) {
if (items.get(position).getId()== 1){
return ITEM_TYPE_C_T;
}
else if(items.get(position).getId()== 2){
return ITEM_TYPE_S_B;
}else {
return ITEM_TYPE_C_T;//(DEFAULT)
}
}
#Override
public int getItemCount() {
return items.size();
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
if (viewType == ITEM_TYPE_S_B){
View view = layoutInflater.inflate(R.layout.segment_nOne,parent,false);
return new BackViewHolder(view);
} else if(viewType == ITEM_TYPE_C_T) {
View view = layoutInflater.inflate(R.layout.segment_nTwo,parent,false);
return new ChestViewHolder(view);
}else{
//to prevent crash on null
View view = layoutInflater.inflate(R.layout.nOne,parent,false);
return new DefaultViewHolder(view);
}
}
This is the object
public class Object {
private int id;
public Object(){ }
public Object(int id){
this.id = id;
}
public int getId(){
return id;
}
Thanks for any help
In my SectionsListAdapter adapter i have nested Adapter named MonthLessonsList, after get date from web service and set new data and call notifyDataSetChanged method for adapter, main adapter as SectionsListAdapter can be refresh, but nested adapter dont refresh and after calling notifyDataSetChanged for that, doesn't work correctly and don't show new data
call and set new data from Fragment:
monthSectionsItems = SQLite.select().from(MonthSections.class).queryList();
adapter.setData(monthSectionsItems);
and my Adapter with nested adapter:
public class SectionsListAdapter extends RecyclerView.Adapter<SectionsListAdapter.MyViewHolder> {
private final OnItemSelected listener;
private List<MonthSections> list;
private Context context;
private MonthLessonsList lessonsListAdapter;
public SectionsListAdapter(List<MonthSections> followingsList, Context mContext, OnItemSelected listener) {
this.list = followingsList;
this.context = mContext;
this.listener = listener;
}
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.sections_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, final int position) {
holder.indicatorIcon.setText(list.get(position).getSection_month_name());
...
List<SectionLesson> lessonsList = list.get(position).getLessons();
lessonsListAdapter = new MonthLessonsList(lessonsList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
holder.userChildCategories.setLayoutManager(mLayoutManager);
holder.userChildCategories.setAdapter(lessonsListAdapter);
...
}
#Override
public int getItemCount() {
return list.size();
}
public void setData(List<MonthSections> data) {
list.clear();
list.addAll(data);
notifyDataSetChanged();
lessonsListAdapter.notifyDataSetChanged();
}
public List<MonthSections> getData() {
return list;
}
class MyViewHolder extends RecyclerView.ViewHolder {
...
public MyViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
section_title.setGravity(Gravity.RIGHT);
}
}
public class MonthLessonsList extends RecyclerView.Adapter<MonthLessonsList.LessonsViewHolder> {
private List<SectionLesson> lessonItem;
public class LessonsViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public LessonsViewHolder(View view) {
super(view);
title = view.findViewById(R.id.title);
}
}
public MonthLessonsList(List<SectionLesson> lists) {
this.lessonItem = lists;
}
#Override
public LessonsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.child_list_row, parent, false);
return new LessonsViewHolder(itemView);
}
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull LessonsViewHolder holder, int position) {
SectionLesson lesson = lessonItem.get(position);
holder.title.setText("درس: " + (position + 1) + ") " + lesson.getTitle());
}
#Override
public int getItemCount() {
return lessonItem.size();
}
}
}
Declare child adapter inside onBindViewHolder, and remove from global level.
And no need to notify child adapter. Because that will be automatically filled when parent onBindViewHolder is called.
Like
MonthLessonsList lessonsListAdapter = new MonthLessonsList(lessonsList);
holder.userChildCategories.setAdapter(lessonsListAdapter);
I have to two data sets with different adapters inside a single activity and I want to use notifyDataSetChanged() however its not working for the other adapter. So inside my adapterFirst class I have LongCLickListener which is using notifyDataSetChanged() and I want to call the adapterSecond to notify too if adapterFirst is updated. The AdapterSecond data is not being updated when pressing LongClick
public class AdapterFirst extends RecyclerView.Adapter <AdapterFirst .ViewHolder> {
private List<Object> objectList;
private Context mContext;
AdapterSecond adapterSecond;
public AdapteFirst(List<Object> list) { objectList= list; }
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//query method
notifyDataSetChanged(); //working
//here it gets the nullpointerexception error
adapterSecond = new AdapteSecond();
adapterSecond.notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return (objectList != null? objectList.size():0);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView data;
public ViewHolder(View itemView) {
super(itemView);
data= (TextView) itemView.findViewById(R.id.text);
}
}
}
AdapterSecond
public class AdapterSecond extends
RecyclerView.Adapter <AdapterSecond.ViewHolder> {
private List<Object> objectList;
private Context mContext;
public AdapterSecond () {}
public AdapterSecond (List<Object> list) { objectList= list; }
#Override
public AdapterSecond.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_2, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final AdapterSecond.ViewHolder holder, int position) {
final Object object = objectList.get(holder.getAdapterPosition());
holder.data2.setText(object.getData());
}
#Override
public int getItemCount() {
return (objectList != null? objectList.size():0);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView data2;
public ViewHolder(View itemView) {
super(itemView);
data2= (TextView) itemView.findViewById(R.id.text2);
}
}
}
Seems like the order of initialization of the adapters have some issues.
Just make sure that you have initialize the secondAdapter before the firstAdapter
secondAdapter= new SecondAdapter();
firstAdapter = new FirstAdapter();
Just check the order in which they initialize!
Edit
As It is a genericAdapter not simple one and I know the methods to add click listener. And it is not a good practice to do this in onCreateViewHolder. So that's why I need a better suggestion
I have created a Generic Adapter for RecyclerView in android. Now I want some suggestion to improve it. And how could I add clickListener to it.
GenericAdapter.java
public abstract class GenericAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private ArrayList<T> items;
private OnRecyclerItemClicked onRecyclerItemClicked;
public abstract RecyclerView.ViewHolder setViewHolder(ViewGroup parent);
public abstract void onBindData(RecyclerView.ViewHolder holder, T val);
public GenericAdapter(Context context, ArrayList<T> items){
this.context = context;
this.items = items;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder = setViewHolder(parent);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
onBindData(holder,items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
public void addItems( ArrayList<T> savedCardItemz){
items = savedCardItemz;
this.notifyDataSetChanged();
}
public T getItem(int position){
return items.get(position);
}
public void setOnRecyclerItemClicked(OnRecyclerItemClicked onRecyclerItemClicked){
this.onRecyclerItemClicked = onRecyclerItemClicked;
}
public interface OnRecyclerItemClicked{
void onItemClicked(View view,int position);
}
}
And Call it like
adapter = new GenericAdapter<MyModelClass>(context,listOfModelClass) {
#Override
public RecyclerView.ViewHolder setViewHolder(ViewGroup parent) {
final View view = LayoutInflater.from(context).inflate(R.layout.item_recycler_view, parent, false);
AViewHolder viewHolder = new AViewHolder(context, view);
return viewHolder;
}
#Override
public void onBindData(RecyclerView.ViewHolder holder1, MyModelClass val) {
MyModelClass currentCard = val;
AViewHolder holder = (AViewHolder)holder1;
holder.cardNumber.setText(currentCard.getDisplayNumber());
holder.cardHolderName.setText(currentCard.getCardHolderName());
}
};
mRecyclerView.setAdapter(adapter);
Now how and where could I add a click listener. As adding click listener to onBindData is an overhead. Need suggestion.
Have you tried adding a ViewHolder and add the clicklistener to it
Now GenericAdapter.java.
public abstract class GenericAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<T> items;
private OnRecyclerItemClicked onRecyclerItemClicked;
public abstract RecyclerView.ViewHolder setViewHolder(ViewGroup parent , OnRecyclerItemClicked onRecyclerItemClicked);
public abstract void onBindData(RecyclerView.ViewHolder holder, T val);
public abstract OnRecyclerItemClicked onGetRecyclerItemClickListener();
public GenericAdapter(Context context, List<T> items){
this.context = context;
this.items = items;
onRecyclerItemClicked = onGetRecyclerItemClickListener();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder = setViewHolder(parent , onRecyclerItemClicked);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
onBindData(holder,items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
public void setItems( ArrayList<T> savedCardItemz){
items = savedCardItemz;
this.notifyDataSetChanged();
}
public T getItem(int position){
return items.get(position);
}
public interface OnRecyclerItemClicked{
void onItemClicked(View view,int position);
}
}
And calling it like this
GenericAdapter<CreditCardItemBO> adaptering = new GenericAdapter<CreditCardItemBO>(mContext,new ArrayList<CreditCardItemBO>()) {
#Override
public RecyclerView.ViewHolder setViewHolder(ViewGroup parent, OnRecyclerItemClicked onRecyclerItemClicked) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.item_save_credit_card, parent, false);
CreditCardViewHolder viewHolder = new CreditCardViewHolder(mContext, view,onRecyclerItemClicked);
return viewHolder;
}
#Override
public void onBindData(RecyclerView.ViewHolder holder, CreditCardItemBO val) {
}
#Override
public OnRecyclerItemClicked onGetRecyclerItemClickListener() {
return new OnRecyclerItemClicked() {
#Override
public void onItemClicked(View view, int position) {
}
};
}
};
You can add the listener in the activity you have declared the RecyclerView:
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, recyclerView,
new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
//Handle the action
}
}
#Override
public void onLongClick(View view, int position) {
}
}));
I have implemented ViewHolder in Santa solution like this:
public class EmployeeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView employeeName;
private BaseRecyclerAdapter.OnRecyclerItemClicked mOnRecyclerItemClicked;
public EmployeeViewHolder(View view, BaseRecyclerAdapter.OnRecyclerItemClicked onRecyclerItemClicked) {
super(view);
employeeName = (TextView) view.findViewById(R.id.employee_name);
mOnRecyclerItemClicked = onRecyclerItemClicked;
view.setOnClickListener(this);
}
#Override
public void onClick(View view) {
mOnRecyclerItemClicked.onItemClicked(view, getAdapterPosition());
}
public TextView getEmployeeName() {
return employeeName;
}
}
If you need the context ad it in to constructor as a parameter.
I have created a generic adapter, the aar and the sources are at this url:
it's easy usage:
RecyclerAdapter<Customer> mAdapter = new RecyclerAdapter(customerList, CustomerViewHolder.class);
add attach listener (lambda sample)
RecyclerItemClickListener.affectOnItemClick(mRecycler, (position, view1) -> {
//action
});
see Url link more details