FirestoreRecyclerAdaptor not showing first item added to firestore - android

I have a fragment called today, in which i get all the tasks with the current day. But, when i add an item to the firestore with the current day, and this is the first task witch is added to the firestore, the task is now showed in the fragment, when I add the second task is showed, and the third the same. But the first task is never showed, do you know why is doing this?
This is today fragment:
public class TodayFragment extends Fragment {
private View rootView;
private TodayAdaptor todayAdaptor;
private ColorDrawable swipeBackgroundRight = new ColorDrawable(Color.parseColor("#FF0000"));
private Drawable iconDelete;
private FirebaseFirestore firestore = FirebaseFirestore.getInstance();
private CollectionReference collectionReference;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (getActivity() != null) {
getActivity().setTitle(R.string.today);
}
collectionReference = firestore.collection("Users")
.document(FirebaseAuth.getInstance().getCurrentUser().getUid())
.collection("Tasks");
iconDelete = ContextCompat.getDrawable(getActivity(), R.drawable.ic_delete);
rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_today, container, false);
RecyclerView recyclerViewToday = rootView.findViewById(R.id.recycler_view_today);
/* create the options for query */
Calendar calendar = Calendar.getInstance();
String dateFormatted = java.text.DateFormat.getDateInstance(java.text.DateFormat.FULL).format(calendar.getTime());
Query query = collectionReference.whereEqualTo("date", dateFormatted);
FirestoreRecyclerOptions<Task> options =
new FirestoreRecyclerOptions.Builder<Task>()
.setQuery(query, Task.class)
.build();
todayAdaptor = new TodayAdaptor(options);
recyclerViewToday.setHasFixedSize(true);
recyclerViewToday.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerViewToday.setAdapter(todayAdaptor);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
if (direction == ItemTouchHelper.RIGHT) {
todayAdaptor.deleteTask(viewHolder.getAdapterPosition());
Toast.makeText(getActivity(), "Task deleted", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
View itemView = viewHolder.itemView;
int iconMargin = (itemView.getHeight() - iconDelete.getIntrinsicHeight()) / 2;
if (dX > 0) {
swipeBackgroundRight.setBounds(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
iconDelete.setBounds(itemView.getLeft() + iconMargin, itemView.getTop() + iconMargin, itemView.getLeft() + iconMargin + iconDelete.getIntrinsicWidth(), itemView.getBottom() - iconMargin);
} else {
swipeBackgroundRight.setBounds(0, 0, 0, 0);
}
c.save();
swipeBackgroundRight.draw(c);
if (dX > 0) {
c.clipRect(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
} else {
c.clipRect(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
}
iconDelete.draw(c);
c.restore();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}).attachToRecyclerView(recyclerViewToday);
return rootView;
}
#Override
public void onStart() {
super.onStart();
todayAdaptor.startListening();
}
#Override
public void onStop() {
super.onStop();
todayAdaptor.stopListening();
}
}
This is my adaptor:
public class TodayAdaptor extends FirestoreRecyclerAdapter<Task, TodayAdaptor.TodayViewHolder> {
public TodayAdaptor(#NonNull FirestoreRecyclerOptions<Task> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull TodayViewHolder holder, int position, #NonNull Task model) {
holder.todayCheckBox.setChecked(model.isCompleted());
holder.taskDescription.setText(model.getName());
}
#NonNull
#Override
public TodayViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.today_item, parent, false);
return new TodayViewHolder(view);
}
public void deleteTask(int position){
/* save the item to be
restored if the user want's so
*/
getSnapshots().getSnapshot(position).getReference().delete();
}
class TodayViewHolder extends RecyclerView.ViewHolder {
private CheckBox todayCheckBox;
private TextView taskDescription;
public TodayViewHolder(#NonNull View itemView) {
super(itemView);
todayCheckBox = itemView.findViewById(R.id.today_item_check_box);
taskDescription = itemView.findViewById(R.id.today_item_task_description);
}
}
}

Related

Detaching item touch helper callback from recycler view

How do I go about doing this for a swipe action for items in a recycler view?
This is my item touch helper class:
public class RecyclerTouchHelper extends ItemTouchHelper.SimpleCallback {
private final RecyclerTouchHelperListener listener;
boolean swipeAllowed;
private static final String TAG = RecyclerTouchHelper.class.getSimpleName();
public RecyclerTouchHelper(int dragDirs, int swipeDirs, RecyclerTouchHelperListener listener, boolean swipeAllowed) {
super(dragDirs, swipeDirs);
this.listener = listener;
this.swipeAllowed = swipeAllowed;
}
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().onSelected(foregroundView);
}
}
#Override
public void onChildDrawOver(#NonNull Canvas c, #NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void clearView(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((MealPlanAdapter.MealPlanDetailsViewHolder) viewHolder).foregroundView;
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAbsoluteAdapterPosition());
}
#Override
public boolean isItemViewSwipeEnabled() {
return swipeAllowed;
}
#Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
public interface RecyclerTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
}
}
And this is a function in the fragment/activity that is triggered via an action from the recycler adapter:
ItemTouchHelper.SimpleCallback itemTouchHelperCallback;
#Override
public void onScrollCheck(boolean allowSwipe) {
if (!allowSwipe) {
itemTouchHelperCallback = new RecyclerTouchHelper(0, 0, this, false);
itemTouchHelperCallback = null;
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(null);
} else {
itemTouchHelperCallback = new RecyclerTouchHelper(0, ItemTouchHelper.LEFT, this, true);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(mealplanRecycler);
}
}
My problem is that no matter what I do, once swiping is turned on it remains allowed and I cannot turn it off. Is it something I am doing wrong when defining and assigning the callback?
Where are you setting swipeAllowed back to false?
You seem to be setting it true first time round and then keep hitting
else {
itemTouchHelperCallback = new RecyclerTouchHelper(0, ItemTouchHelper.LEFT, this, true);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(mealplanRecycler);
}
As it was never set back to false?

How to disable Swipe left and up in RecyclerView?

I want to perform only the right swipe on RecyclerView.
But it swipes on both sides and also an upside.
How to disable swipe left and up?
Want to perform delete functionality on the right swipe.
It works but it swipes all the side of items. How to prevent this?
NotificationFragment.java
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
if (viewHolder instanceof NotificationListAdapter.ViewHolder) {
mAdapter.removeItem(viewHolder.getAdapterPosition());
}
}
NotificationListAdapter.java
public void removeItem(int position) {
callDeleteService(position);
}
RecyclerItemTouchHelper
public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
public RecyclerItemTouchHelper(int dragDirs ,int swipeDirs ,RecyclerItemTouchHelperListener listener) {
super( dragDirs ,swipeDirs );
this.listener = listener;
}
#Override
public boolean onMove(RecyclerView recyclerView ,RecyclerView.ViewHolder viewHolder ,RecyclerView.ViewHolder target) {
return true;
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder ,int actionState) {
if (viewHolder != null) {
final View foregroundView = ((NotificationListAdapter.ViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().onSelected( foregroundView );
}
}
#Override
public void onChildDrawOver(Canvas c ,RecyclerView recyclerView ,
RecyclerView.ViewHolder viewHolder ,float dX ,float dY ,
int actionState ,boolean isCurrentlyActive) {
final View foregroundView = ((NotificationListAdapter.ViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().onDrawOver( c ,recyclerView ,foregroundView ,dX ,dY ,
actionState ,isCurrentlyActive );
}
#Override
public void clearView(RecyclerView recyclerView ,RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((NotificationListAdapter.ViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().clearView( foregroundView );
}
#Override
public void onChildDraw(Canvas c ,RecyclerView recyclerView ,
RecyclerView.ViewHolder viewHolder ,float dX ,float dY ,
int actionState ,boolean isCurrentlyActive) {
final View foregroundView = ((NotificationListAdapter.ViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().onDraw( c ,recyclerView ,foregroundView ,dX ,dY ,
actionState ,isCurrentlyActive );
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder ,int direction) {
// if (direction == ItemTouchHelper.END){
listener.onSwiped( viewHolder ,direction ,viewHolder.getAdapterPosition() );
// }
// else {
// Log.d( "Swipe LEFT : ", " DO NOTHING" );
// }
}
#Override
public int getMovementFlags(RecyclerView recyclerView ,RecyclerView.ViewHolder viewHolder) {
int dragFlags = 0;
int swipeFlags = ItemTouchHelper.LEFT;
return makeMovementFlags( dragFlags ,swipeFlags );
}
#Override
public int convertToAbsoluteDirection(int flags ,int layoutDirection) {
return super.convertToAbsoluteDirection( flags ,layoutDirection );
}
public interface RecyclerItemTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder ,int direction ,int position);
}
}
I want it like a 1st image.
We can define swipe directions by using SimpleCallback().
For RIGHT:
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.RIGHT, this);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
For LEFT:
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
For Both:
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);

RecyclerView swipe to delete in Fragment

I made an swipe to delete functionality in my recycleView and i want to add another background when item is swiped across the screen.
I'm using tutorial for this: https://medium.com/#zackcosborn/step-by-step-recyclerview-swipe-to-delete-and-undo-7bbae1fce27e
I wrote some code, but i have an java.lang.IllegalStateException: Fragment PatientsFragment{dcddb65} not attached to a context.
public class PatientsFragment extends Fragment {
ClinicViewModel clinicViewModel;
private final ColorDrawable background= new ColorDrawable(getResources().getColor(R.color.colorPrimary));
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.patients_fragment, container, false);
FloatingActionButton fab = root.findViewById(R.id.fabAddPatient);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddPatientFragment addPatientFragment = new AddPatientFragment();
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.nav_host_fragment, addPatientFragment)
.addToBackStack(null)
.commit();
}
});
RecyclerView recyclerView = (RecyclerView) root.findViewById(R.id.recyclerViewPatients);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setHasFixedSize(true);
final PatientsAdapter adapter = new PatientsAdapter();
recyclerView.setAdapter(adapter);
clinicViewModel = ViewModelProviders.of(this).get(ClinicViewModel.class);
clinicViewModel.getAllPatients().observe(this, new Observer<List<Patient>>() {
#Override
public void onChanged(List<Patient> patients) {
adapter.setPatients(patients);
}
});
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
View itemView = viewHolder.itemView;
int backgroundCornerOffset = 20;
if (dX > 0) { // Swiping to the right
background.setBounds(itemView.getLeft(), itemView.getTop(),
itemView.getLeft() + ((int) dX) + backgroundCornerOffset,
itemView.getBottom());
} else if (dX < 0) { // Swiping to the left
background.setBounds(itemView.getRight() + ((int) dX) - backgroundCornerOffset,
itemView.getTop(), itemView.getRight(), itemView.getBottom());
} else { // view is unSwiped
background.setBounds(0, 0, 0, 0);
}
background.draw(c);
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
clinicViewModel.deletePatient(adapter.getPatientAt(viewHolder.getAdapterPosition()));
Toast.makeText(getActivity(), "Patient deleted", Toast.LENGTH_SHORT).show();
}
}).attachToRecyclerView(recyclerView);
return root;
}
}
Any ideas why?
Thanks in advance!

The deleted item is empty when invoke UNDO button on snackbar

I'm trying to implement the feature "Swipe to delete" item in recycleview. But the deleted item is can not restore correctly when invoke UNDO action on snackbar.
This is error.
https://i.imgur.com/hPfaBQX.png
I have tried to implement onChildDraw in different ways, but it does not work
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
// backup of removed item
final String deletedItem = adapter.arrIgnoreNumber.get(viewHolder.getAdapterPosition());
final int deletedIndex = viewHolder.getAdapterPosition();
adapter.removeItem(viewHolder.getAdapterPosition());
// showing snack bar with Undo option
Snackbar snackbar = Snackbar.make(coordinatorLayout, "Removed from the list!", Snackbar.LENGTH_LONG);
snackbar.setAction("UNDO", new View.OnClickListener() {
#Override
public void onClick(View view) {
adapter.restoreItem(deletedItem, deletedIndex);
}
});
snackbar.setActionTextColor(Color.YELLOW);
snackbar.show();
}
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
Bitmap icon;
Paint p = new Paint();
if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
View itemView = viewHolder.itemView;
float height = (float) itemView.getBottom() - (float) itemView.getTop();
float width = height / 3;
if(dX > 0){
p.setColor(Color.parseColor("#388E3C"));
RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_delete);
RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,p);
} else {
p.setColor(Color.parseColor("#D32F2F"));
RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),(float) itemView.getRight(), (float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_delete);
RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width,(float) itemView.getRight() - width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,p);
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
I expect the deleted item can restore in list
Update: I provide my adapter for more detail:
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.list_ignore_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
final int tmpPos = position;
viewHolder.phone.setText(arrIgnoreNumber.get(position));
String name = arrIgnoreNumber.get(position);
if (!name.isEmpty()) {
viewHolder.phone.setVisibility(View.VISIBLE);
viewHolder.name.setText(name);
} else {
viewHolder.phone.setVisibility(View.GONE);
viewHolder.name.setText(arrIgnoreNumber.get(position));
}
viewHolder.icon.setImageBitmap(Utils.getBitmapByContactNumber(mContext, arrIgnoreNumber.get(position), false));
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
return arrIgnoreNumber.size();
}
public void removeItem(int position) {
arrIgnoreNumber.remove(position);
notifyItemRemoved(position);
}
public void restoreItem(String item, int position) {
arrIgnoreNumber.add(position, item);
notifyItemInserted(position);
}
The following solution works for me. Refer to https://www.androidhive.info/2017/09/android-recyclerview-swipe-delete-undo-using-itemtouchhelper/
In ItemTouchHelper.SimpleCallback:
#Override
public int getMovementFlags(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(0, ItemTouchHelper.LEFT);
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
}
#Override
public void onSelectedChanged(#Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((IgnoreCallAdapter.ViewHolder) viewHolder).foreground;
getDefaultUIUtil().onSelected(foregroundView);
}
}
#Override
public void onChildDrawOver(#NonNull Canvas c, #NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((IgnoreCallAdapter.ViewHolder) viewHolder).foreground;
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((IgnoreCallAdapter.ViewHolder) viewHolder).foreground;
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
#Override
public void clearView(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((IgnoreCallAdapter.ViewHolder) viewHolder).foreground;
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public float getSwipeThreshold(#NonNull RecyclerView.ViewHolder viewHolder) {
return 0.7f;
}
#Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
In item layout xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/row_view_height_ignore_list"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/ignore_item_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/ignore_item_bg">
</RelativeLayout>
<LinearLayout
android:id="#+id/ignore_item_foreground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg_ignore_item_foreground"
android:orientation="horizontal"
android:visibility="visible">
</LinearLayout>
</LinearLayout>
</FrameLayout>

Calculating total price of items in a List of Items in a recyclerview

I want to calculate the price of items in a List and store the value in sharedpreference. Each Item has a price which takes the form of a double.The issue is when i use my method, it only takes into account one item in the list and calculates for that value. I am using a NumberPicker to change the quantity of the items.
Here is my adapter for handling the List of items that will be displayed on the RecyclerView:
public class CartAdapter extends RecyclerView.Adapter<CartAdapter.ViewHolder> {
private List<SingleItem> items;
private SessionManager sessionManager;
private Context context;
private int pos;
public CartAdapter() {
}
public CartAdapter(Context context, List<SingleItem> items) {
this.items = items;
this.context = context;
sessionManager = new SessionManager(context);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cartitem, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final SingleItem singleItem = items.get(position);
holder.tv_title.setText(singleItem.getTitle());
holder.tv_price.setText("Ksh: " + singleItem.getPrice());
Picasso.with(context).load(singleItem.getUrl()).fit().into(holder.imgcart);
holder.numcart.setMinValue(1);
holder.numcart.setMaxValue(15);
holder.numcart.setWrapSelectorWheel(false);
int qty = holder.numcart.getValue();
getTotal(qty, singleItem.getPrice());
}
public double getTotal(int value, double amount){
double totalamount;
double amountall = amount;
int quantity = value;
totalamount = amountall * quantity;
sessionManager.grandtotal("Ksh: " + totalamount);
return totalamount;
}
#Override
public int getItemCount() {
return items.size();
}
public void removeItem(SingleItem item) {
sessionManager.removeitem(context,item);
items.remove(item);
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_price;
TextView tv_title;
NumberPicker numcart;
ImageView imgcart;
public ViewHolder(View view) {
super(view);
tv_price = (TextView) view.findViewById(R.id.titlecart);
tv_title = (TextView) view.findViewById(R.id.pricecart);
numcart = (NumberPicker) view.findViewById(R.id.pickercart);
imgcart = (ImageView) view.findViewById(R.id.imgcart);
}
}
}
Here is how i'm displaying the RecyclerView on the fragment:
public class Details extends Fragment {
private RecyclerView RecyclerDetails;
private TextView CartPrice;
private CheckBox CheckCart;
private List<SingleItem> list;
private CartAdapter adapter;
private boolean add = false;
private Paint p = new Paint();
private SessionManager sessionManager;
private int pos;
public Details() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_details, container, false);
RecyclerDetails = (RecyclerView) view.findViewById(R.id.recyclercart);
CartPrice = (TextView) view.findViewById(R.id.tvcarttotal);
CheckCart = (CheckBox) view.findViewById(R.id.chkcart);
sessionManager = new SessionManager(getContext());
Toasty.info(getContext(),"Swipe to go to Next", Toast.LENGTH_SHORT,true).show();
RecyclerDetails.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
RecyclerDetails.setLayoutManager(layoutManager);
list = sessionManager.getItems(getContext());
HashMap<String,String> map = sessionManager.itemstostring();
String data = map.get(SessionManager.KEY_ITEMS);
Log.i(Constants.TAG,data);
HashMap<String,String> tot = sessionManager.getgrandtotal();
String total = tot.get(SessionManager.KEY_TOTAL);
CartPrice.setText(total);
CheckCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()){
sessionManager.saveditems("true");
} else {
sessionManager.saveditems("false");
}
}
});
RecyclerDetails.addOnItemTouchListener(new RecyclerItemClickListener(getContext(), new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}));
if(list != null){
adapter = new CartAdapter(getContext(),list);
RecyclerDetails.setAdapter(adapter);
}
initswipe();
return view;
}
private void initswipe() {
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
if (direction == ItemTouchHelper.RIGHT) {
adapter.removeItem(list.get(position));
sessionManager.saveitems(getContext(),list);
}
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
Bitmap icon;
if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
View itemView = viewHolder.itemView;
float height = (float) itemView.getBottom() - (float) itemView.getTop();
float width = height / 3;
if(dX > 0){
p.setColor(Color.parseColor("#14a895"));
RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_delete);
RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,p);
} else {
p.setColor(Color.parseColor("#14a895"));
RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),(float) itemView.getRight(), (float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(getResources(),android.R.drawable.ic_menu_delete);
RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width,(float) itemView.getRight() - width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,p);
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(RecyclerDetails);
}
}
And finally, here is the function i use to store the value of the total of all items in the list
public void grandtotal (String total){
editor.putString(KEY_TOTAL,total);
editor.commit();
}
public HashMap<String, String> getgrandtotal(){
HashMap<String, String> tot = new HashMap<>();
tot.put(KEY_TOTAL,pref.getString(KEY_TOTAL,null));
return tot;
}
Is there a function I haven't included in the fragment where I'm displaying the RecyclerView with the items ?
Is it just a small change needed ?
private int grandTotal(List<SingleItem> items){
int totalPrice = 0;
for(int i = 0 ; i < items.size(); i++) {
totalPrice += items.get(i).getPrice();
}
return totalPrice;
}
this is the method u need to implement to get the grand total price. U can call this method when u r adding an item or removing and item from the list.
This function in kotlin
var total = 0;
for ( i in 0 until myDebt.size){
total += myDebt[i].valueAdp
}
this is the method you need to implement to get the grand total price. can call this method within your activity
 and you can still assign the value to textView.
mtv_my_debt.setText(String.valueOf(total))

Categories

Resources