How can Increase/Decrease Particular Item quantity in Cart Functionality inside RecyclerView? - java

I am working on a cart items based project. In which I have to Increase/Decrease Order item Quantity Two Button. Every Thing is Fine But on Particular Item Increase/Decrease Value it can't count from 1 .it can get Previous count Value.
Screenshot
Here is My RecyclerAdapter Code.
public class CheckOutAdapter extends RecyclerView.Adapter<CheckOutAdapter.MyVHolder> {
ArrayList<CartModel> itemsList;
Context context;
OnItemClickListner mListner;
int quantity;
public CheckOutAdapter(ArrayList<CartModel> itemsList, Context context) {
this.context = context;
this.itemsList = itemsList;
}
#NonNull
#Override
public MyVHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.inflator_for_checkoutfrag, parent, false);
return new MyVHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyVHolder holder, int position) {
/*holder.catgry_txt_title.setText(itemsList.get(position).title);
holder.catgry_img.setImageResource(itemsList.get(position).img);*/
holder.itemName.setText(itemsList.get(position).CartIteMname);
holder.itemPartNo.setText(itemsList.get(position).cartItemno);
holder.finalprice.setText(String.format("%s $", itemsList.get(position).totalprice));
Picasso.with(context).load(itemsList.get(position).carPart_imgURL).into(holder.itemIMG);
quantity = Integer.parseInt(itemsList.get(position).cartQuantity);
if (quantity == 1) {
holder.txtQuantity.setText(String.valueOf(quantity));
}
holder.btnIncrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//int count= Integer.parseInt(String.valueOf(holder.txtQuantity.getText()));
quantity++;
holder.txtQuantity.setText(String.valueOf(quantity));
}
});
holder.btnDecrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int count= Integer.parseInt(String.valueOf(holder.txtQuantity.getText()));
if (quantity>1)
quantity--;
holder.txtQuantity.setText(String.valueOf(quantity));
}
});
}
#Override
public int getItemCount() {
Log.e("adapterLSize",String.valueOf(itemsList.size()));
return itemsList.size();
}
class MyVHolder extends RecyclerView.ViewHolder {
ImageView itemIMG, removeCart, btnIncrease, btnDecrease;
TextView cartItemTitle, itemName, itemPartNo, finalprice, txtQuantity;
LinearLayout addtoCart;
MyVHolder(View itemView) {
super(itemView);
cartItemTitle = itemView.findViewById(R.id.cartItemTitle);
itemName = itemView.findViewById(R.id.itemName);
itemPartNo = itemView.findViewById(R.id.itemPartNo);
finalprice = itemView.findViewById(R.id.finalprice);
itemIMG = itemView.findViewById(R.id.itemIMG);
txtQuantity = itemView.findViewById(R.id.txtQuantity);
btnIncrease = itemView.findViewById(R.id.btnIncrease);
btnDecrease = itemView.findViewById(R.id.btnDecrease);
removeCart = itemView.findViewById(R.id.removeCart);
}
}
}
My Question:
How can Increase/Decrease Particular Item quantity in Cart Functionality inside RecyclerView in android?

You just need to do this:
myViewHolder.btnIncrease.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View v) {
int count= Integer.parseInt(String.valueOf(myViewHolder.tvQuantity.getText()));
count++;
myViewHolder.tvQuantity.setText("" + count);
}
});
myViewHolder.btnDecrease.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View v) {
int count= Integer.parseInt(String.valueOf(myViewHolder.tvQuantity.getText()));
if (count == 1) {
myViewHolder.tvQuantity.setText("1");
} else {
count -= 1;
myViewHolder.tvQuantity.setText("" + count);
}
}
});

In the onClick for increase, you are directly using the quantity variable which is common to all items. This means it can have the quantity of another item than the one being pressed.
For decrease, you are correctly setting it to the current value for that particular item before decrementing it. Doing the same in increase should fix it. Though you seem to have commented that line for some reason?
A better approach would be to get the corresponding item from itemsList and increment or decrement the cartQuantity variable, and use that. The current method of parsing the text being shown is an extremely roundabout way of keeping track.

Here is the code You looking for /* method for quantity*/
public void Positive(View view) { /* call on +*/
String a = display Integer.get Text().to String().trim(); int ab = Integer.parseInt(a); abfg = abfg + 1; display(abfg);
}
public void decreaseNegative(View view) { /call on -/
String bcd = displayInteger.getText().toString().trim(); int vc = Integer.parseInt(bcd); Toast.makeText(getApplicationContext(),String.valueOf(vc),Toast.LENGTH_LONG).show(); if(vc>1) {
vc = vc - 1;
}
/* if(vc<0){ vc=1; }*/ display(vc); }
private void display(int number) { // To display displayInteger.setText("" + number); text = displayInteger.getText().toString(); quant = Integer.parseInt(text); }

You can also use com.cepheuen.elegantnumberbutton.view.ElegantNumberButton
from GitHub.
Then add this in your Gradle implementation:
com.cepheuen.elegant-number-button:lib:1.0.2

Related

Get ArrayList value and set it to a TextView on Button Click Not Working - RecyclerView

My last question hopefully for this week.. I have set up a RecyclerView with an Array that iterates through numbers 0 - 350 in increments of 10. This pops up as an overlay over the activity by clicking a TextView (dailyGoal). Once a value has been selected, the chosen value should be set to the TextView.
This is all working fine, the value does set, however it sets the value as the first value, which is 10 mins. I think this is because the onItemClicked is pointing to the RecyclerView as a whole and not the Recycler TextView (time), there is a method included for it, however whenever I try to use it, the onClick function does nothing..
I think this one is a simple solution but I've been messing around with it for a while and can't find a working solution..
Activity
ArrayList<String> dailyGoalTime;
int[] timeArray = new int[360];
dailyGoal.setText("60");
dailyGoalRecycler.setVisibility(View.GONE);
dailyGoalTime = new ArrayList<>();
for (int i = 0; i < timeArray.length; i++) {
timeArray[i] = i;
}
for (int i = 0; i < timeArray.length; i++) {
if (i % 10 == 0 && i != 0) {
dailyGoalTime.add(i + " mins");
}
}
ItemClickSupport.addTo(dailyGoalRecycler).setOnItemClickListener(
new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
dailyGoal.setText(timeArray[i]);
dailyGoalRecycler.setVisibility(View.GONE);
}
#Override
public void onItemClicked(TextView time, int position, View view) {
// this does nothing
// dailyGoal.setText(dailyGoalTime.get(timeArray[i]));
// dailyGoalRecycler.setVisibility(View.GONE);
}
}
);
Interface
public interface OnItemClickListener {
void onItemClicked(RecyclerView recyclerView, int position, View v);
void onItemClicked(TextView time, int position, View view);
}
Adapter
ArrayList<String> dailyGoalTime;
ItemClickSupport.OnItemClickListener listener;
public DailyGoalAdapter(ArrayList<String> dailyGoalTime) {
this.dailyGoalTime = dailyGoalTime;
}
#NonNull
#Override
public DailyGoalAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull DailyGoalAdapter.ViewHolder holder, int position) {
holder.time.setText(dailyGoalTime.get(position));
}
#Override
public int getItemCount() {
return dailyGoalTime.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView time;
public ViewHolder(#NonNull View itemView) {
super(itemView);
time = itemView.findViewById(tvTime);
}
}
You forgot the most important part. You need to call the interface method on item click like this:
holder.itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
listener.onItemClicked(holder.time, position, holder.itemView);
}
)};

Recycler ItemClick doesn't work with Countdown timer

I'm trying to develop Letters and Numbers(Countdown) like game. In this concept, user should able to use the arithmetic operations results of given numbers once for the reach goal number in a given time.
I'm using the Recyclerview to show and list the steps of calculation but while Countdown Timer ticking, I can't click the items of recyclerview. It only works when the Countdown Timer finished up.
Please help me to find out the problem.
Here is what I mean as a image: https://hizliresim.com/zWThaa
Here is my adapter
public interface OnItemListener{
void onItemClick(int position);
}
private OnItemListener mOnItemListener;
private ArrayList<String> n1;
private ArrayList<String> n2;
private ArrayList<String> res;
private ArrayList<String> op;
public NotesRecyclerAdapter(ArrayList<String> n1, ArrayList<String> n2, ArrayList<String> res, ArrayList<String> op, OnItemListener onItemListener) {
this.n1 = n1;
this.n2 = n2;
this.res = res;
this.op = op;
this.mOnItemListener = onItemListener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item, parent, false);
return new ViewHolder(view, mOnItemListener);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
if(n2.size() <= position ){
holder.second.setText(" ");
}
else{
holder.second.setText(n2.get(position));
}
if(op.size() <= position){
holder.operation.setText(" ");
}
else{
holder.operation.setText(op.get(position));
}
if (res.size() <= position){
holder.result.setText(" ");
}
else {
holder.result.setText(res.get(position));
}
holder.first.setText(n1.get(position));
}
#Override
public int getItemCount() {
return n1.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView first;
TextView operation;
TextView second;
TextView result;
OnItemListener mOnItemListener;
public ViewHolder(View itemView, OnItemListener onItemListener) {
super(itemView);
first = itemView.findViewById(R.id.first);
operation = itemView.findViewById(R.id.op);
second = itemView.findViewById(R.id.secondNum);
result = itemView.findViewById(R.id.res);
this.mOnItemListener = onItemListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
mOnItemListener.onItemClick(getAdapterPosition());
}
}
}
Here is Activity,
public class CalculateActivity extends AppCompatActivity implements Adapter.OnItemListener{
RecyclerView rView;
Adapter adapter;
.//Other definitions etc.
.
protected void onCreate(Bundle savedInstanceState) {
. . . // Other
adapter = new Adapter(firstNumbers,secondNumbers,operationResults,operators,this);
rView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
rView.setAdapter(adapter);
new CountDownTimer(45000, 1) {
#Override
public void onTick(long millisUntilFinished) {
// Calculation step
}
#Override
public void onFinish() {
}
}.start();
...//Button Listeneres etc...
} // end of onCreate
#Override
public void onItemClick(int position) {
System.out.println(position + " Clicked!");
View view = rView.getChildAt(position);
TextView res = view.findViewById(R.id.res);
moveCount++;
if(moveCount % 2 == 0){
firstNumbers.add((String)res.getText()); //res is textview of the operation results.
}
else{
secondNumbers.add((String)res.getText());
}
view.setClickable(false)
dataChange(); //just notifyDataSetChange
}
PS: I also used this method. I can able to click with this method but it returns wrong value of item's position while Countdown Timer ticking. Just like I explained above, it works perfectly when the timer runs out.
Probably you have a problem with adapter...
I don't know what you do in the onTick method, whether you block something or...
I'm not sure what do you want but consider whether it is possible to do so
You can create Step class like
public class Step {
private String first;
private String operation;
private String second;
private String result;
private boolean disabled; //instead view clickable
//TODO generate getters and setters
}
Try this adapter
public class NotesRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final OnItemListener mOnItemListener;
private final List<Step> items;
public NotesRecyclerAdapter(List<Step> items, OnItemListener onItemListener) {
this.items = items;
this.mOnItemListener = onItemListener;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item, parent, false);
return new NotesViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
NotesViewHolder mHolder = (NotesViewHolder) holder;
Step item = items.get(position);
mHolder.first.setText(item.getFirst());
if(items.size() <= position){ // Im not sure why this
mHolder.second.setText(" ");
mHolder.operation.setText(" ");
mHolder.result.setText(" ");
}else{
mHolder.second.setText(item.getSecond());
mHolder.operation.setText(item.getOperation());
mHolder.result.setText(item.getResult());
}
if(mOnItemListener != null){
mHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mOnItemListener.onItemClick(mHolder.getAdapterPosition());
}
});
}
}
#Override
public int getItemCount() {
return items.size();
}
public Step getItem(int position) {
if(this.items == null || position < 0 || position >= this.items.size()) return null;
return this.items.get(position);
}
public interface OnItemListener{
void onItemClick(int position);
}
public static class NotesViewHolder extends RecyclerView.ViewHolder {
public TextView first;
public TextView operation;
public TextView second;
public TextView result;
public NotesViewHolder(View itemView) {
super(itemView);
first = itemView.findViewById(R.id.first);
operation = itemView.findViewById(R.id.op);
second = itemView.findViewById(R.id.secondNum);
result = itemView.findViewById(R.id.res);
}
}
}
and onClick method
#Override
public void onItemClick(int position) {
Toast.makeText(this, "Clicked: "+ position, Toast.LENGTH_SHORT).show();
Step step = adapter.getItem(position);
if(step != null){
if(step.isDisabled()){
Toast.makeText(this, "Disabled"+ position, Toast.LENGTH_SHORT).show();
return;
}
moveCount++;
if(moveCount % 2 == 0){
step.setFirst(random number or what); //how do you get number, randomly or...
} else{
step.setSecond(random number or what);
}
step.setDisabled(false); //instead view.setClickable(false)
dataChange(); //just notifyDataSetChange
}
}

When I am in last Item In CardStackView?

I have RecyclerView(CardStackView) With 60 items.
Now After finish All Items .. I have Blank Page .. I do not want to Show The blank Page if all items finished ... I want to Intent to Another Activity You can see The blank Page Here
when I implement CardStackListener I Added Those Method too Like This .I want to When All card Answered Intent To ResultActivity...Like This After 60th question I want InstedOf Blank Page Intent To ResultActivity
//Card Method
#Override
public void onCardDragging(Direction direction, float ratio) {
Log.d("CardStackView", "onCardDragging: d = " + direction.name() + ", r = " + ratio);
}
#Override
public void onCardSwiped(Direction direction) {
Log.d("CardStackView", "onCardSwiped: p = " + manager.getTopPosition() + ", d = " + direction);
if (manager.getTopPosition() == mbtiQuestAdapter.getItemCount() - 5) {
mbtiQuestAdapter.addQuestion(questions);
mbtiQuestAdapter.notifyDataSetChanged();
}
position++;
Intent intent = new Intent(MbtiQuestionActivity.this, ResultActivity.class);
intent.putExtra(RESULT, result);
Log.i(TAG, "onResultClick: " + result);
startActivity(intent);
}
#Override
public void onCardRewound() {
Log.d("CardStackView", "onCardRewound: " + manager.getTopPosition());
}
#Override
public void onCardCanceled() {
Log.d("CardStackView", "onCardCanceled:" + manager.getTopPosition());
}
Adapter.java
public class MbtiQuestAdapter extends RecyclerView.Adapter<MbtiQuestAdapter.MbtiQuestViewHolder> {
private List<Question> questionList;
private LayoutInflater layoutInflater;
private final OnItemClickListener listener;
private static final String TAG = "MbtiQuestAdapter";
public interface OnItemClickListener {
void onItemClick(int position, char value);
}
public MbtiQuestAdapter(List<Question> questionList, OnItemClickListener listener) {
this.questionList = questionList;
this.listener = listener;
}
#NonNull
#Override
public MbtiQuestViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (layoutInflater == null) {
layoutInflater = LayoutInflater.from(parent.getContext());
}
MbtiItemRowBinding binding = DataBindingUtil.inflate(layoutInflater,
R.layout.mbti_item_row, parent, false);
return new MbtiQuestViewHolder(binding);
}
#Override
public void onBindViewHolder(#NonNull final MbtiQuestViewHolder holder, final int position) {
final Question question = questionList.get(position);
holder.binding.txtQuesNum.setText(String.valueOf(position + 1));
holder.binding.txtQuesTitle.setText(question.getQuestion());
holder.binding.firstQues.setText(question.getAnswers().get(0).getAnswer());
holder.binding.secondQues.setText(question.getAnswers().get(1).getAnswer());
holder.binding.firstQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(position, question.getAnswers().get(0).getValue());
}
});
holder.binding.secondQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(position, question.getAnswers().get(1).getValue());
}
});
holder.binding.setQuestion(question);
}
#Override
public int getItemCount() {
Log.i(TAG, " List Size : " + questionList.size());
return questionList.size();
}
class MbtiQuestViewHolder extends RecyclerView.ViewHolder {
private MbtiItemRowBinding binding;
MbtiQuestViewHolder(MbtiItemRowBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
public void addQuestion(List<Question> questions) {
this.questionList.addAll(questions);
}
}
SetUp CardStackView In Activity
//Swipe RecyclerView with CardStackView
cardStackView = binding.cardStackView;
manager = new CardStackLayoutManager(this);
mbtiQuestAdapter = new MbtiQuestAdapter(questions, this);
cardStackView.setLayoutManager(manager);
cardStackView.setAdapter(mbtiQuestAdapter);
I want to Say If The items Finished Do SomeThing (Show Dialog or etc.)
Thank Guys
Working Code
private CardStackView cardStackView;
private CardStackLayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//
layoutManager = new CardStackLayoutManager(getApplicationContext(), this);
cardStackView.setLayoutManager(layoutManager);
//
}
#Override
public void onCardSwiped(Direction direction) {
if (layoutManager.getTopPosition() == adapter.getItemCount()) {
// -------------------- last position reached, do something ---------------------
startActivity(new Intent(this, MainActivity.class));
}
}
You have CardStackLayoutManager. When card is swiped, callback comes in onCardSwiped.
Here you will get top position (position displayed on top), and total item count.
If top_position == total_item_count, then it is last position, now you can do anything.
Below is Output or same
Use position to check if you have arrived to last item. Inside onBindViewHolder method
if( position+ 1 == questionList.size()){
// you are at the last item
}
You ca try this by using scrollChangeListener like :
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LinearLayoutManager layoutManager=LinearLayoutManager.class.cast(recyclerView.getLayoutManager());
int totalItemCount = layoutManager.getItemCount();
int lastVisible = layoutManager.findLastVisibleItemPosition();
boolean endHasBeenReached = lastVisible + 5 >= totalItemCount;
if (totalItemCount > 0 && endHasBeenReached) {
//you have reached to the bottom of your recycler view
}
}
});
Some code correction, it is better not to create listeners in onBindViewHolder() because it will be set each time this method called, better to set ones in ViewHolder
For example :
Override
public void onBindViewHolder(#NonNull final MbtiQuestViewHolder holder, final int position) {
holder.bind(questionList.get(position))
}
class MbtiQuestViewHolder extends RecyclerView.ViewHolder {
private MbtiItemRowBinding binding;
MbtiQuestViewHolder(MbtiItemRowBinding binding) {
super(binding.getRoot());
this.binding = binding;
binding.firstQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(getAdapterPosition(), questionList.get(getAdapterPosition()).getAnswers().get(0).getValue());
}
});
binding.secondQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(getAdapterPosition(), questionList.get(getAdapterPosition()).getAnswers().get(1).getValue());
}
});
}
public void bind(Question question){
binding.txtQuesNum.setText(String.valueOf(position + 1));
binding.txtQuesTitle.setText(question.getQuestion());
binding.firstQues.setText(question.getAnswers().get(0).getAnswer());
binding.secondQues.setText(question.getAnswers().get(1).getAnswer());
binding.setQuestion(question);
}
public void addQuestion(List<Question> questions) {
this.questionList.addAll(questions);
}
}
you could compare with CardStackLayoutManager.getTopPosition(), which should be the index position currently displayed. the CardStackView GitHub explains the methods which are available.
alternatively, just count the number of swipes:
int currentPosition = 0;
#Override
public void onCardSwiped(Direction direction) {
currentPosition++;
}
//define the layoutmanager
private CardStackLayoutManager manager;
//make CardStackListener in layout manger and u need to implement methods
manager = new CardStackLayoutManager(this, new CardStackListener() {
#Override
public void onCardDragging(Direction direction, float ratio) {
}
#Override
public void onCardSwiped(Direction direction) {
}
#Override
public void onCardRewound() {
}
#Override
public void onCardCanceled() {
}
#Override
public void onCardAppeared(View view, int position) {
//here if u print position you will find the position of your viewed item and this function will call when card viewed
}
#Override
public void onCardDisappeared(View view, int position) {
Log.d("onCardDisappeared: ", "" + position);
//here if u print position you will find the position of your Disappeared item and this function will call when card disappear
}
}
});
cardStackView.setLayoutManager(manager);
cardStackView.setAdapter(cardStackAdapter);

Update textview from Recyclerview Adapter class

I'm working on a E-commerce App to place some online orders. In my Recyclerview there are products, which are added at the previous activity. Here i'm populating the added products in the Recyclerview with the details such as item name, qty, price etc.. There are buttons to increase/decrease the qty of each products and another button to delete the item too.
At the bottom of the Recyclerview Layout there is another textview to Show the grand total. As I'm handling the button slicks in the RecyclerViewAdapter class, while user updating the qty or deleting an item, I have to update the Grand total. I tried some solutions already mentioned here, but the app crashes at random button clicks. Please provide a solution or a better way to do this.
Here is my Adapter class:
public class InvoiceRecyclerViewAdapter extends RecyclerView.Adapter<InvoiceRecyclerViewAdapter.ViewHolder> {
private static final String TAG = "RecylerViewAdapter";
List<Products> addedProductsList;
Context mContext;
public InvoiceRecyclerViewAdapter(Context mContext,List<Products> addedProductsList)
{
this.mContext=mContext;
this.addedProductsList=addedProductsList;
}
public InvoiceRecyclerViewAdapter(Context mContext)
{
this.mContext=mContext;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_invoice,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.item_qty.setText("1");
holder.itemname.setText(addedProductsList.get(position).getName());
holder.itemprice.setText("Rs "+addedProductsList.get(position).getPrice());
holder.itemdiscount.setText("Rs "+calculate_dis(position));
holder.itemtotal.setText("Rs "+calculate_total(position));
holder.button_inc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qty = addedProductsList.get(position).getQty();
qty++;
addedProductsList.get(position).setQty(qty);
holder.item_qty.setText(""+qty);
holder.itemdiscount.setText("Rs "+calculate_dis(position));
holder.itemtotal.setText("Rs "+calculate_total(position));
UpdateTotal();
}
});
holder.button_dec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qty = addedProductsList.get(position).getQty();
qty--;
if(qty>0){
addedProductsList.get(position).setQty(qty);
holder.item_qty.setText(""+qty);
holder.itemdiscount.setText("Rs"+calculate_dis(position));
holder.itemtotal.setText("Rs"+calculate_total(position));
UpdateTotal();
}
}
});
holder.button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addedProductsList.get(position).setAddedTocart(false);
//notifyDataSetChanged();
addedProductsList.remove(position);
notifyItemRemoved(position);
UpdateTotal();
}
});
}
#Override
public int getItemCount() {
return addedProductsList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView itemname,itemtotal,itemprice,itemdiscount,item_qty;
Button button_cancel,button_inc,button_dec;
ConstraintLayout parent_layout;
public ViewHolder(View itemView) {
super(itemView);
itemname = itemView.findViewById(R.id.textView_item_name);
itemprice = itemView.findViewById(R.id.textView_item_price);
itemdiscount = itemView.findViewById(R.id.textView_item_discount);
itemtotal = itemView.findViewById(R.id.textView_item_total);
button_cancel = itemView.findViewById(R.id.button_cancel);
button_inc=itemView.findViewById(R.id.button_inc);
button_dec=itemView.findViewById(R.id.button_dec);
item_qty = itemView.findViewById(R.id.textView_qty);
parent_layout = itemView.findViewById(R.id.invoice_parent_layout);
}
}
private float calculate_dis(int pos){
float dis = 0;
if(addedProductsList.get(pos).isPrice_g_enabled()){
int qty=addedProductsList.get(pos).getQty();
dis = Float.parseFloat(addedProductsList.get(pos).getPrice())-Float.parseFloat(addedProductsList.get(pos).getPrice_g());
dis = qty*dis;
}
return dis;
}
private float calculate_total(int pos){
int qty=addedProductsList.get(pos).getQty();
float price,total;
if(addedProductsList.get(pos).isPrice_g_enabled()){
price = Float.parseFloat(addedProductsList.get(pos).getPrice_g());
}
else{
price= Float.parseFloat(addedProductsList.get(pos).getPrice());
}
total = price*qty;
return total;
}
private void UpdateTotal(){
TextView txtView =((EditQuantity)mContext).findViewById(R.id.textView_total);
float total=0,price=0;
int qty=0;
for(int i=0;i<addedProductsList.size();i++){
if(addedProductsList.get(i).isAddedTocart()) {
qty = addedProductsList.get(i).getQty();
if(addedProductsList.get(i).isPrice_g_enabled()){
price = Float.parseFloat(addedProductsList.get(i).getPrice_g());
}
else{
price= Float.parseFloat(addedProductsList.get(i).getPrice());
}
}
total=total+(qty*price);
}
txtView.setText("Rs "+total);
}
}
Here is the Main Activity part:
public class EditQuantity extends AppCompatActivity {
ArrayList<Products> products_list;
ArrayList<Products> cart_productslist= new ArrayList<>();
Products added_product;
FloatingActionButton fab_next;
TextView total_textview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_quantity);
products_list = getIntent().getParcelableArrayListExtra("products");
Products products;
for(int i=0;i<products_list.size();i++){
products = products_list.get(i);
if(products.isAddedTocart()){
added_product = new Products(products.getName(),products.getPrice(),products.getPrice_g(),products.getImage(),1,true,products.isPrice_g_enabled());
cart_productslist.add(added_product);
}
}
Toolbar toolbar = findViewById(R.id.toolbar_invoice);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Cart");
total_textview = findViewById(R.id.textView_total);
total_textview.setText("Rs "+CalTotal());
fab_next = findViewById(R.id.fab_next);
fab_next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
InitRecylerView();
}
#Override
public void onBackPressed() {
}
private void InitRecylerView() {
RecyclerView recyclerView = findViewById(R.id.invoice_recyclerview);
InvoiceRecyclerViewAdapter adapter = new InvoiceRecyclerViewAdapter(
this ,cart_productslist);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public float CalTotal(){
float total=0;
float i_total,price;
for(int i=0;i<cart_productslist.size();i++){
if(cart_productslist.get(i).isAddedTocart()) {
int qty = cart_productslist.get(i).getQty();
if(cart_productslist.get(i).isPrice_g_enabled()){
price = Float.parseFloat(cart_productslist.get(i).getPrice_g());
}
else{
price= Float.parseFloat(cart_productslist.get(i).getPrice());
}
i_total = price * qty;
total = total + i_total;
}
}
return total;
}
I'd suggest going through a listener, moving your onClickListeners and removing the for loops.
So, step by step
In your adapter class declare an interface
public interface OnQuantityChangeListener {
void onQuantityChange( float change );
}
Next add a private OnQuantityChangeListener to your adapter class and change the constructor to add one at creation:
private OnQuantityChangeListener mListener;
public InvoiceRecyclerViewAdapter(Context mContext,List<Products> addedProductsList, OnQuantityChangeListener listener) {
this.mContext=mContext;
this.addedProductsList=addedProductsList;
mListener = listener;
}
public InvoiceRecyclerViewAdapter(Context mContext, OnQuantityChangeListener listener)
{
this.mContext=mContext;
mListener = listener;
}
It's bad for performance to set OnClickListeners in the onBindViewHolder method, because this means you're going to have to add them any time a view pops up onto the screen. Set them in the onCreateViewHolder method instead, that way you'll recycle them. To get your current item you can use the getAdapterPosition() method.
So in the onCreateViewHolder method set the listeners:
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_invoice,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.button_inc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Products product = addedProductsList.get(getAdapterPosition());
product.setQty( product.getQty() + 1 );
float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());
mListener.onQuantityChange( difference );
notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you
}
});
viewHolder.button_dec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Products product = addedProductsList.get(getAdapterPosition());
if( product.getQty() == 0 )// Can't remove an item if it's already at 0
return;
product.setQty( product.getQty() - 1 );
float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());
mListener.onQuantityChange( -difference );
notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you
}
});
viewHolder.button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Products product = addedProductsList.get(getAdapterPosition());
float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());
mListener.onQuantityChange( -difference * product.getQty() );
product.setQty( 0 );
notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you
// You decide at this point if you want to remove the item altogether or just show 0
}
});
return viewHolder;
}
Remember at this point to remove the OnClickListeners from your onBindViewHolder method.
Once this is done head over to your Activity and add a private total:
private float total = 0;
and edit your adapter creation like so:
InvoiceRecyclerViewAdapter adapter = new InvoiceRecyclerViewAdapter(
this ,cart_productslist, new InvoiceRecyclerViewAdapter.OnQuantityChangeListener(){
#Override
void onQuantityChange( float difference ){
total += difference;
total_textview.setText("Rs "+ total);
}
} );
And that about does it. Remember to calculate your first total in your activity once (no escaping the for loop here) and then make sure you save your instance states.
Hope this helps!

Highlight item in CaseListActivity when user clicked on buttons in detail fragment

I'm using a Master-Detail layout from the android studio. I've managed to highlight the menu items when the page first load or when user clicked on the menu item. For my detail page, I have added two buttons, "Next" and "Previous" which enable user to go through the menu items when user clicked on it. My question is How do I get the menu item highlighted in-sync with detail page ? I managed to get the correct item highlight when I rotated the device.
MainFragment.java
public class Keputusan extends Fragment {
...
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final TextView button_prev = (TextView) view.findViewById(R.id.btn_prev);
TextView button_next = (TextView) view.findViewById(R.id.btn_nxt);
PageTransition.pageContents(this, CaseContent.getSize(), "formA",
getArguments().getString(ARG_ITEM_ID), button_next, button_prev);
}
}
CaseListActivity.java
public class CaseListActivity extends BaseActivity {
int selectedItem = 0; //current item on list
...
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.mItem = mValues.get(position);
holder.mContentView.setText(mValues.get(position).content);
holder.mIcon.setText(mValues.get(position).icon);
if(selectedItem == position || position == PageTransition.getItemPosition()) {
holder.mView.setSelected(true);
//Change text color when highlighted
holder.mContentView.setTextColor(ContextCompat.getColor(getApplicationContext(),
R.color.colorPrimary));
}
else {
holder.mView.setSelected(false);
holder.mContentView.setTextColor(ContextCompat.getColor(getApplicationContext(), android.R.color.black));
}
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedItem = position;
onSelectedMenuItem(holder.mItem.id, v);
notifyDataSetChanged(); //make system recognize selectedItem = position
}
});
}
...
}
PageTransition.java
public class PageTransition {
public static final String TAG = PageTransition.class.getSimpleName();
private static int pageId;
....
public static void pageContents(final Fragment fragment, int totalPage, final String form, String id, TextView next,
TextView previous) {
//change string string to int
int pageID = Integer.parseInt(id);
int prevID = 0, nextID = 0;
if(pageID == 1) {
previous.setVisibility(View.GONE); //hide prev button onn 1st page
nextID = ++pageID;
} else if (pageID > 1 && pageID < totalPage ) {
prevID = --pageID;
nextID = 2+pageID;
} else if (pageID == totalPage) {
next.setVisibility(View.GONE); //hide next button on last page
prevID = --pageID;
}
final int finalNextID = nextID;
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment _fragment = init(String.valueOf(finalNextID), form);
fragment.getFragmentManager().beginTransaction()
.replace(R.id.case_detail_container, _fragment).commit();
}
});
final int finalPrevID = prevID;
previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment _fragment = init(String.valueOf(finalPrevID), form);
fragment.getFragmentManager().beginTransaction()
.replace(R.id.case_detail_container, _fragment).commit();
}
});
}
//highlighted menu items in next & prev
public static int getItemPosition() {
//since position starts with "1"
Log.d(TAG, "getId: pageID " + pageId);
return pageId - 1 ;
}
....
}
I wasn't able to find the solution on how to directly accessed the recycler view from another activity. Instead, I called the next & pre button inside the CaseListActivity (the same file as the recycler view) then, inside the ViewHolder, I set the Next & prev onClickedListeners. I don't know whether it was the correct way.... but it did the job done.

Categories