I have the following Code:
public static FirestoreRecyclerAdapter adapter;
private void loadList() {
Query query = db.collection("x").document(firebase_user_uid).collection("x");
FirestoreRecyclerOptions<Note> response = new FirestoreRecyclerOptions.Builder<Note>()
.setQuery(query, Note.class)
.build();
adapter = new FirestoreRecyclerAdapter<Note, NoteViewHolder>(response) {
#Override
protected void onBindViewHolder(NoteViewHolder holder, int position, Note model) {
final Note note = notesList.get(position);
holder.title.setText(note.getTitle());
holder.content.setText(note.getContent());
if (note.getNote_image_url() != null) {
Glide.with(MainActivity.this).load(note.getNote_image_url()).into(holder.bg_note_image);
holder.bg_note_image.setVisibility(View.VISIBLE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateNote(note);
}
});
}
#Override
public NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_view, parent, false);
return new NoteViewHolder(view);
}
#Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
#Override
public int getItemCount() {
return notesList.size();
}
public void removeItem(int position) {
notesList.remove(position);
// notify the item removed by position
// to perform recycler view delete animations
// NOTE: don't call notifyDataSetChanged()
notifyItemRemoved(position);
}
public void restoreItem(Note item, int position) {
notesList.add(position, item);
// notify item added by position
notifyItemInserted(position);
}
};
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
SO, a simple FirestoreRecyclerAdapter. But now I need to call the removeItemMethod inside the adapter. But how to do this?
I tried something like this, but all that didn't work.
public void deleteItem(int position) {
adapter.removeItem(position);
}
I am sitting so long on this Problem. I hope anywhere is a solution to my Problem.
Thanks in advance.
~mb
You get this message because the original FirestoreRecyclerAdapter does not have this method. You should create a separate class extending FirestoreRecyclerAdapter and use it when creating an adapter.
public class MyAdapter extends FirestoreRecyclerAdapter<Note, NoteViewHolder> {
public List<Notes> notesList;
public MyAdapter(List<Notes> notes, FirestoreRecyclerOptions<Note> response) {
super(response);
notesList = notes;
}
#Override
protected void onBindViewHolder(NoteViewHolder holder, int position,
Note model) {
final Note note = notesList.get(position);
holder.title.setText(note.getTitle());
holder.content.setText(note.getContent());
if (note.getNote_image_url() != null) {
Glide.with(MainActivity.this).load(note.getNote_image_url()).into(holder.bg_note_image);
holder.bg_note_image.setVisibility(View.VISIBLE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateNote(note);
}
});
}
#Override
public NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_view, parent, false);
return new NoteViewHolder(view);
}
#Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
#Override
public int getItemCount() {
return notesList.size();
}
public void removeItem(int position) {
notesList.remove(position);
// notify the item removed by position
// to perform recycler view delete animations
// NOTE: don't call notifyDataSetChanged()
notifyItemRemoved(position);
}
public void restoreItem(Note item, int position) {
notesList.add(position, item);
// notify item added by position
notifyItemInserted(position);
}
}
Something like this. And when you create an adapter :
public static MyAdapter adapter;
And initialising it:
adapter = new MyAdapter(response)
Also, it is not a good idea to keep an adapter static.
Edit: pass the items - notesList - in the constructor.
Related
Inside my Firestore Cloud-Storage I got this Boolean-field inside Products/Productid/: "isOffer".
I want to change the color of the TextView-String "mPrice" inside my RecyclerView ProductItems, regarding if "isOffer" is true or false, but I have no Idea how to handle that.
Method createRecycler():
public void createRecycler(){
mRecyclerView = findViewById(R.id.product_selection_list);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
Query query = current_productRef.whereEqualTo("isAvailable", true);
FirestoreRecyclerOptions<product_selection_Item> options = new FirestoreRecyclerOptions.Builder<product_selection_Item>()
.setQuery(query, product_selection_Item.class)
.build();
mAdapter = new product_selection_Adapter(options);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new product_selection_Adapter.OnItemClickListener() {
#Override
public void OnItemClick(DocumentSnapshot documentSnapshot, int position) {
String id = documentSnapshot.getId();
Intent intent = new Intent(product_selection.this, product_fill.class);
intent.putExtra("Product_ID", id);
startActivity(intent);
}
});
}
My Adapter for the Recycler is pretty basic:
public class product_selection_Adapter extends FirestoreRecyclerAdapter<product_selection_Item, product_selection_Adapter.product_selection_ViewHolder> {
private OnItemClickListener mListener;
public interface OnItemClickListener {
void OnItemClick(DocumentSnapshot documentSnapshot, int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public class product_selection_ViewHolder extends RecyclerView.ViewHolder {
public TextView mProductname;
public TextView mFat_Value;
public TextView mPrice;
public product_selection_ViewHolder(#NonNull View itemView, final OnItemClickListener listener) {
super(itemView);
mProductname = itemView.findViewById(R.id.product_selection_name);
mFat_Value = itemView.findViewById(R.id.product_selection_fat);
mPrice = itemView.findViewById(R.id.product_selection_price);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.OnItemClick(getSnapshots().getSnapshot(position), position);
}
}
}
});
}
}
public product_selection_Adapter(#NonNull FirestoreRecyclerOptions<product_selection_Item> options) {
super(options);
}
#NonNull
#Override
public product_selection_ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_selection_item, parent, false);
product_selection_ViewHolder ViewHolder = new product_selection_ViewHolder(v, mListener);
return ViewHolder;
}
#SuppressLint("SetTextI18n")
#Override
protected void onBindViewHolder(#NonNull product_selection_ViewHolder holder, int position, #NonNull product_selection_Item model) {
holder.mProductname.setText(model.getmProductname());
holder.mFat_Value.setText(String.valueOf(model.getmFat_Value() + "% Fett"));
holder.mPrice.setText(String.valueOf(model.getmPrice().get(0) + " €"));
}
}
Can you help me out here?
Thank you in Advance!
I solved it.
I needed to create a new Attribute inside my Product_Selection_Item - Class "isOffer" with the getter "getisOffer".
After that, inside the Adapter I simply created a new boolean variable "isOffer" which gets the value of the current bool. Just like:
protected void onBindViewHolder(#NonNull product_selection_ViewHolder holder, int position, #NonNull product_selection_Item model) {
holder.mProductname.setText(model.getmProductname());
holder.mFat_Value.setText(String.valueOf(model.getmFat_Value() + "% Fett"));
holder.mPrice.setText(String.valueOf(model.getmPrice().get(0) + " €"));
holder.isOffer = model.getisOffer();
if(holder.isOffer){
holder.mPrice.setTextColor(Color.parseColor("#D90000"));
}
else{
holder.mPrice.setTextColor(Color.parseColor("#000000"));
}
}
Don't know, if that's the best solution, but it worked for me! :)
Edit:
This only works like that, because I'm using the FirestoreUI with the FirestoreRecyclerAdapter.
Here, every getter with the Attribute of the Product_Selection_Item which has the same name inside the Firestore Storage, will be connected automatically to Firestore.
That's why I simply can do "holder.isOffer = model.getisOffer();"
My Recycler view is not updating after an item is removed.
This recyclerView is inside a fragment.
I have tried every method and nothing works.
Adapter declaration in fragment class
notificationsTabAdapter = new NotificationsTabAdapter(getContext(), R.id.notificationsRecyclerView,
notificationItemsList, cListner);
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(notificationsTabAdapter);
RecyclerViewAdapter:
public class NotificationsTabAdapter extends RecyclerView.Adapter<NotificationsTabAdapter.NotificationItemHolder> {
Boolean debug = false;
public static final String NOTIFICATION_ADAPTER = "NotificationAdapter";
private ArrayList<NotificationItemm> notificationItems;
private int layoutResID;
private int notificationposition;
private Context myContext;
public onNotificationItemClickListner mListner;
public interface onNotificationItemClickListner {
void onNotificationItemDelete(int position);
}
public NotificationsTabAdapter(Context context, int resource, ArrayList<NotificationItemm> notificationList,
onNotificationItemClickListner listner) {
myContext = context;
layoutResID = resource;
notificationItems = notificationList;
notificationposition = 0;
this.mListner = listner;
}
#NonNull
#Override
public NotificationItemHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.notifications_tab_item, viewGroup, false);
NotificationsTabAdapter.NotificationItemHolder evh = new NotificationsTabAdapter.NotificationItemHolder(view, mListner);
return evh;
}
#Override
public void onBindViewHolder(#NonNull final NotificationItemHolder notificationItemHolder, final int position) {
final NotificationItemm currentItem = notificationItems.get(position);
notificationItemHolder.mNotificationTextView.setText(currentItem.getNotification_name());
notificationItemHolder.mNotificationURL = currentItem.getNotification_link();
notificationItemHolder.mNotificationDate = currentItem.getNotification_date();
notificationItemHolder.mNotificationRT = currentItem.getNotification_rT();
notificationItemHolder.mNotificaionHolderLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
//to delete the notification
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteNotification(currentItem);
mListner.onNotificationItemDelete(position);
}
});
}
#Override
public int getItemCount() {
return notificationItems.size();
}
//Delete from View
public void deleteNotification(NotificationItemm todelete) {
int notificationPosition = notificationItems.indexOf(todelete);
notificationItems.remove(notificationPosition);
notifyItemRemoved(notificationPosition);
notifyItemChanged(notificationPosition);
notifyDataSetChanged();
notifyItemRemoved(notificationPosition);
notifyItemChanged(notificationPosition);
if (notificationItems.isEmpty()) {
}
}
/**
* VIEW HOLDER =================================================================================
**/
public class NotificationItemHolder extends RecyclerView.ViewHolder {
RelativeLayout mNotificaionHolderLayout;
RelativeLayout notificationParentRelative;
ImageView imageDelete;
TextView mNotificationTextView;
String mNotificationURL;
String mNotificationDate;
String mNotificationRT;
public NotificationItemHolder(#NonNull View itemView, onNotificationItemClickListner listner) {
super(itemView);
mNotificationTextView = itemView.findViewById(R.id.NotificationTextView);
mNotificaionHolderLayout = itemView.findViewById(R.id.notification__item_container);
imageDelete = itemView.findViewById(R.id.notification_delete_image);
notificationParentRelative = itemView.findViewById(R.id.rlNotificLayout);
mNotificationRT = null;
mNotificationURL = null;
mNotificationDate = null;
}
}
}
When I debug the project, I can see that the item is actually removing from the ArrayList.But not updating in recycled view.
After deletion, if the recyclerview is scrolled, the deleted item is removed from the recyclerview.But not without scrolling.
Try this.Hope will work for you.
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
notificationItems.remove(position);
notifyDataSetChanged();
}
In your NotificationsTabAdapter make the following changes
NotificationsTabAdapterListener notificationsTabAdapterListener;
public interface NotificationsTabAdapterListener { // create an interface
void onItemsDeleted(int position); // create callback function
}
public NotificationsTabAdapter(Context context, int resource, ArrayList<NotificationItemm> notificationList,
NotificationsTabAdapterListener notificationsTabAdapterListener) {
myContext = context;
layoutResID = resource;
notificationItems = notificationList;
notificationposition = 0;
this.notificationsTabAdapterListener = notificationsTabAdapterListener;
}
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//perform normal remove operation here
notificationItems.remove(position);
notificationsTabAdapterListener.onItemsDeleted(position);
}
});
And Implement NotificationsTabAdapterListener in you fragment and in override method use the following code
#Override
public void onItemsDeleted(final int position) {
notificationsTabAdapter.notifyDataSetChanged();
recyclerView.post(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(position);
}
});
}
Try this to your delete functionality
public void deleteNotification(NotificationItemm todelete) {
notificationItems.remove(todelete);
notifyDataSetChanged();
}
As workaround you can call a method in the FragmentClass, which loads the new list (with item removed) in your adapter. Call this method from your Adapter
public void MethodInFragmentClass(NotificationItemm todelete)
{
/*
... delete item
*/
notificationsTabAdapter = new NotificationsTabAdapter(getContext(), R.id.notificationsRecyclerView,
notificationDeletedItemsList, cListner);
recyclerView.setAdapter(notificationsTabAdapter);
}
Use a callback like this in your adapter :
private ICallback mICallback;
public interface ICallback {
void deleteItem(int position);
}
public SettingRecyclerViewAdapter(SettingMediator settingMediator, ICallback ICallback) {
mICallback = ICallback;
mSettingMediator = settingMediator;
}
And in your faragment notifydatasetchange and update recyclerview like this :
public class YourFragment implements SettingContract.View, SettingRecyclerViewAdapter.ICallback {
.
.
.
#Override
public void deleteItem(int position) {
//delete item from your list here
mSettingRecyclerViewAdapter = new SettingRecyclerViewAdapter(yourList, this);
mRecyclerView.setAdapter(mSettingRecyclerViewAdapter);
mSettingRecyclerViewAdapter.notifyDataSetChanged();
}
}
Try this:
notificationItemHolder.imageDelete.setTag(holder);
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NotificationItemHolder viewholder = (NotificationItemHolder) v.getTag();
notificationItems.remove(viewholder.getAdapterPosition());
notifyDataSetChanged();
}
});
You have to parse the position which is getting from onclick listener in Adapter class to Interface method(onitemClicked())
Then, Implement the interface class to Fragment class and will remove the position which we have on Interface method using [ listname.remove(position)) ]
Eventually, update recyclerview UI using adaptername.notifyDataSetChanged();
Step 1 :create interface class
public interface RecyclerviewItemClickListener {
void onitemClicked(View v, int position);
}
Step 2: pass position to the interface method in adapter class
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteNotification(currentItem);
//use interface method & pass the position of the list to fragment for update UI .
recyclerviewItemClickListener.onitemClicked(v,position);
}
});
step 3 : implement the interface class & method in fragment
#Override
public void onitemClicked(View v, int position) {
Listname.remove(Listname.get(position));
RecyclerviewAdaptername.notifyDataSetChanged();
}
I've implemented a recyclerview with staggered gridLayout containing about 31 items in the arrayList, recyclerview is working correctly, but I faced issue relating to single item selection.
When I select the value till "26" as shown in figure, its working fine
But, when I select the value after "26", the values from top most item are also selected, as shown in this next figure.
I require to only select one item at a time.
I've implemented the following code in my adapter class
public class DialogAdapter extends
RecyclerView.Adapter<DialogAdapter.DialogHolder>
{
// components
public Context context;
public ArrayList<AlertDialogModel> dialogArrayList = new
ArrayList<AlertDialogModel>();
private final ArrayList<Integer> selected = new ArrayList<>();
private int lastCheckedPosition = -1;
public Interface interface;
// parameterized constructor
public DialogAdapter(Context context, ArrayList<AlertDialogModel>
dialogArrayList,Interface interface)
{
this.context = context;
this.dialogArrayList = dialogArrayList;
this.interface = interface;
}
#NonNull
#Override
public DialogHolder onCreateViewHolder(#NonNull ViewGroup parent, int
viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_cardview,parent,false);
DialogHolder dialogHolder = new DialogHolder(view);
return dialogHolder;
}
#Override
public void onBindViewHolder(#NonNull final DialogHolder holder, final int position)
{
final AlertDialogModel alertDialogModel = dialogArrayList.get(position);
holder.textView.setText(alertDialogModel.getDisplayValue());
if(lastCheckedPosition == position)
{
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
}
else
{
}
holder.textView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
lastCheckedPosition = position;
notifyDataSetChanged();
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
interface.getSelectedValue(alertDialogModel.getDisplayValue());
}
});
}
#Override
public int getItemCount()
{
return dialogArrayList.size();
}
public static class DialogHolder extends RecyclerView.ViewHolder
{
public TextView textView;
public DialogHolder(View itemView)
{
super(itemView);
textView = (TextView)itemView.findViewById(R.id.textView);
}
}
}
Can anyone relate my code and identify the issue ?
holder.textView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
lastCheckedPosition = position;
notifyDataSetChanged();
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
interface.getSelectedValue(alertDialogModel.getDisplayValue());
//below line is important to remove previous selected position from the variable
lastCheckedPosition = -1;
}
});
you should put the text view to the original state:
if(lastCheckedPosition == position)
{
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
}
else
{
holder.textView.setTextColor(context.getResources().getColor(R.color.transparent));
holder.textView.setBackground(null));
}
I've a recycler adapter where I've added setOnClickListener for items in adapter. Code is as given below:
#Override
public void onBindViewHolder(final FiltersAdapter.MyViewHolder holder, final int position) {
holder.mOrganizer.setText(filtersList.get(position));
holder.mLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
//Log.e("message","ONclick FIlter");
if (holder.mOrganizerCheck.isChecked()){
holder.mOrganizerCheck.setChecked(false);
}else {
holder.mOrganizerCheck.setChecked(true);
int pos = holder.getAdapterPosition();
filtersList.get(pos);
/*Bundle bundle = new Bundle();
bundle.putInt(pos, );*/
Log.d(TAG, "onClick: " +filtersList);
Log.d(TAG, "onClick of position: " +pos);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
And here is fragment code which deals with getting values from adapter to fragment.
private void initView() {
mrvFilterBySender = (RecyclerView) mFilterView.findViewById(R.id.rvFilterBySender);
mFiltersAdapter = new FiltersAdapter(getActivity(), mListOrganizer);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
mrvFilterBySender.setLayoutManager(mLayoutManager);
mrvFilterBySender.setAdapter(mFiltersAdapter);
mFiltersAdapter.notifyDataSetChanged();
mrvFilterBySender.setAdapter(mFiltersAdapter);
mrvFilterBySender.setRecyclerListener(new RecyclerView.RecyclerListener() {
#Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
holder.getAdapterPosition();
}
});
}
I'm trying to pass pos and value having that pos from adapter to fragment. But my code isn't working. How can I fix it?
make interface to handle click event into recyclerview ..
used below code for handling click event.
onItemClickListner onItemClickListner;
public void setOnItemClickListner(RecyclerViewAdpater.onItemClickListner onItemClickListner) {
this.onItemClickListner = onItemClickListner;
}
public interface onItemClickListner{
void onClick(String str);//pass your object types.
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
String data=mStringList.get(position); // if you pass object of class then create that class object.
holder.textView.setText(data);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListner.onClick(data);
}
});
}
then after when you bind adapter into RecyclerView call below code..
mRvData.setLayoutManager(new LinearLayoutManager(this));
mRvData.setAdapter(recyclerViewAdpater);
recyclerViewAdpater.notifyDataSetChanged();
recyclerViewAdpater.setOnItemClickListner(new RecyclerViewAdpater.onItemClickListner() {
#Override
public void onClick(String str) {
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
}
});
Create an interface in your adapter
public interface OnItemClickListener {
void onItemClicked(int position, Object object);
}
in your adapter call
Adapter adapter = new Adapter(context, list, new Adapter.OnItemClickListener() {
#Override
public void onItemClicked(int position, Object object) {
// Handle Object of list item here
}
});
on your adapter
private OnItemClickListener onItemClickListener; // Global scope
in constructor call:
this.onItemClickListener = onItemClickListener;
on your item clicked event :
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListener.onItemClicked(position, _list.get(position));
}
});
Please use an interface like below, pass it in the adapter's constructor, and than use it in your activity / Fragment
public MyAdapter(Context context, List<Object> data, MyAdapterListener myAdapterListener) {
this.context = context;
this.data = data;
this.myAdapterListener = myAdapterListener;
}
public interface MyAdapterListener {
void onContainerClick(View view, int position);
}
}
public class ViewHolderItem extends RecyclerView.ViewHolder implements View.OnClickListener {
public LinearLayout container;
public ImageView poster;
public ViewHolderItem(View v) {
super(v);
container = (LinearLayout) v.findViewById(R.id.container);
poster = (ImageView) v.findViewById(R.id.poster);
container =setOnClickListener(this); /// this line must include
}
#Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.container) {
if (myAdapterListener != null) {
myAdapterListener.onContainerClick(v,getAdapterPosition());
}
}
}
}
Use it like this in your fragment/Activity
mAdapter = new MyAdapter(getApplicationContext() , data, new MyAdapter.MyAdapterListener() {
#Override
public void onContainerClick(View v, int position) {
Log.d(TAG, "iconTextViewOnClick at position "+position);
}
});
mRecycler.setAdapter(mAdapter);
I thing this is work for you
Add in you adapter
public interface ClickEvent {
void clickEventItem(int position,String value);
}
ClickEvent clickevent;
public void setClickEvent(ClickEvent event) {
this.clickevent = event;
}
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
clickevent.clickEventItem(position, list.get(position));
}
});
in your fragment set interface
adapter.setClickEvent(your class context);
implement ClickEvent intereface and generate #Override method
#Override
public void clickEventItem(int position,String value) {
//write your code here
}
please read before marking it as a duplicate! :)
I converted a listview to recyclerview in my app. But the problem is that it just doesnt update when I call any notify methods. I read that i should call these methods on the Ui Thread. but even that isn't working. The data list has the item added to it but it doesnt get shown on UI.
Here's the code.
Adapter:
public class CustomViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Activity activity;
ArrayList<Leg> data;
public CustomViewAdapter(Activity a, ArrayList<Leg> d) {
super();
activity = a;
data = d;
}
#Override
public int getItemCount() {
return data.size();
}
#Override
public int getItemViewType(int position) {
Leg tempValues = data.get(position);
return tempValues.getLegType();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 1:
//...type 1
case 2:
//...type 2
default:
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_leg, parent, false);
return new LegViewHolder1(v);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Leg tempValues = data.get(position);
//.... Simple view logic that correctly displays
}
class LegViewHolder2 extends RecyclerView.ViewHolder {
//... Holder of another type
}
class LegViewHolder1 extends RecyclerView.ViewHolder {
#InjectView(R.id.leg_add_button)
RelativeLayout legAddIcon;
public AddLegViewHolder(View v) {
super(v);
ButterKnife.inject(this, v);
legAddIcon.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Add Debug", "AddIcon clicked");
Leg leg = new Leg();
leg.setLegType(Constants.LEG);
data.add((data.size() - 1), leg);
refreshList("add", (data.size() - 1)); /// was using notify previously here
}
});
}
}
public void refreshList(final String type, final int position) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
if (type.equals("update")) {
notifyItemChanged(position);
} else if (type.equals("remove")) {
notifyItemRemoved(position);
} else if (type.equals("add")) {
notifyItemInserted(position);
}
}
});
}
}
Here's the Activity:
public class LegActivity extends BaseActivity {
CustomViewAdapter adapter;
LoadTask loadTask = null;
ArrayList<Leg> legsList;
#InjectView(R.id.leg_list)
RecyclerView legList;
#Override
public void onCreate(Bundle savedInstanceState) {
//...boiler plate code
legList.setHasFixedSize(true);
legList.setLayoutManager(new LinearLayoutManager(this));
loadTask = new LoadTask(this);
loadTask.execute();
}
class LoadTask extends RoboAsyncTask<Boolean> {
protected LoadTask(Context context) {
super(context);
}
#Override
protected void onPreExecute() {
// show loader
}
#Override
public Boolean call() throws Exception {
//load some data the send boolean for success
}
#Override
protected void onSuccess(Boolean success) {
//checking for success and loading data to legslist.
adapter = new CustomViewAdapter(LegActivity.this, legsList);
legList.setAdapter(new AlphaInAnimationAdapter(adapter));
legList.setItemAnimator(new SlideInLeftAnimator());
}
#Override
protected void onException(Exception e) {
// other code....
}
}
}
The problem is that the object is added to the actual legList when i click on the add button. I verified that but the notify notifyItemInserted doesnt seem to work. I tried running that on the UI thread but even that didnt seem to work.
Any suggestions? I followed the android recyclerview sample. Maybe i have used the RunOnUiThread incorrectly?
Also if you spot any syntax errors due to name changes, that isnt the problem, on Android Studio the code is error free.
I will take a shot and say it's because of this custom animating adapter:
legList.setAdapter(new AlphaInAnimationAdapter(adapter));
Try it this way:
adapter = new AlphaInAnimationAdapter(new CustomViewAdapter(LegActivity.this, legsList));
legList.setAdapter(adapter);