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!
Related
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
}
}
This question already has answers here:
android.content.res.Resources$NotFoundException: String resource ID #0x0
(8 answers)
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 2 years ago.
I have this restaurant app and I want to make a checkout looking like FoodPanda's (if you have the layout in mind). The recyclerview items should contain a textview containing the quantity of one product, surrounded by two buttons for decrement and increment that quantity, then two textviews with product name and the price.
I've tried this so far in my adapter class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private ArrayList<Product> product;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void decrementQ(int position);
void incrementQ(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class MyViewHolder extends ViewHolder {
public ImageView incrementQty, decrementQty;
public TextView productName, price, qty;
public MyViewHolder(View itemView, final OnItemClickListener listener) {
super(itemView);
incrementQty = itemView.findViewById(R.id.incrementProduct);
decrementQty = itemView.findViewById(R.id.decrementProduct);
qty = itemView.findViewById(R.id.qtyProduct);
productName = itemView.findViewById(R.id.productName);
price = itemView.findViewById(R.id.productPrice);
decrementQty.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION)
listener.decrementQ(position);
}
}
});
incrementQty.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION)
listener.incrementQ(position);
}
}
});
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<Product> thisProduct) {
product = thisProduct;
}
// Create new views (invoked by the layout manager)
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.products, parent, false);
MyViewHolder mv = new MyViewHolder(v, mListener);
return mv;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
Product currentProduct = product.get(position);
holder.decrementQty.setImageResource(currentProduct.getDecrementSource());
holder.qty.setText(currentProduct.getQty());
holder.incrementQty.setImageResource(currentProduct.getIncrementSource());
holder.productName.setText(currentProduct.getProductName());
holder.price.setText(currentProduct.getProductPrice());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return product.size();
}
}
And this is my checkout activity class:
public class checkout extends AppCompatActivity {
private ArrayList<Product> product;
private RecyclerView recyclerView;
private MyAdapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checkout);
product = new ArrayList<>();
product.add(new Product(R.drawable.minus, "1", R.drawable.plus, "Buttered Noodles", "15 RON"));
product.add(new Product(R.drawable.minus, "2", R.drawable.plus, "Teryiaki","20 RON"));
product.add(new Product(R.drawable.minus, "3", R.drawable.plus, "ginger", "3 RON"));
buildCheckout();
}
public void removeItem(int position) {
product.remove(position);
mAdapter.notifyItemRemoved(position);
}
public void buildCheckout(){
recyclerView = findViewById(R.id.checkoutList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
mAdapter = new MyAdapter(product);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
#Override
public void decrementQ(int position) {
TextView q = recyclerView.findViewHolderForAdapterPosition(position).itemView.findViewById(R.id.qtyProduct);
int qty = Integer.parseInt((String) q.getText());
qty--;
if(qty < 1)
removeItem(position);
else
q.setText(qty);
}
#Override
public void incrementQ(int position) {
TextView q = recyclerView.findViewHolderForAdapterPosition(position).itemView.findViewById(R.id.qtyProduct);
int qty = Integer.parseInt((String) q.getText());
qty++;
q.setText(qty);
}
});
}
}
The problem is, when I try to interact with the increment and decrement buttons, the app keeps stoping and I don't know what should I do next or what I did wrong.
you are setting Int value instead of String value to TextView and you will get ResourceNotFoundException:
#Override
public void incrementQ(int position) {
TextView q = recyclerView.findViewHolderForAdapterPosition(position).itemView.findViewById(R.id.qtyProduct);
int qty = Integer.parseInt((String) q.getText());
qty++;
q.setText(qty);//ERROR change to q.setText("" + qty);
}
you have same problem in decrementQ
I have a RecyclerView.Adapter which has some Arrays there.
ArrayList with Strings and ArrayList with Integer. Strings are like url and Integer is the photo.
When the app is open for first time the first item is selected.
I have another method for click which makes another item as selected and this works, but the problem is that the first item stays as selected and so for every image click makes as selected, I want only one item to be selected and take a color.
This is my code.
Adapter of RecyclerView
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder>{
private int selectedItem;
private ArrayList<Integer> mImages = new ArrayList<>();
private ArrayList<String> mSearchUrl = new ArrayList<>();
private Context mContext;
public ListViewAdapter(ArrayList<Integer> images, ArrayList<String> SearchUrl, Context context) {
mImages = images;
mContext = context;
mSearchUrl = SearchUrl;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.s_engine_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int i) {
selectedItem = 0;
if (selectedItem == i) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}
Glide.with(mContext).load(mImages.get(i))
.into(viewHolder.image);
viewHolder.searchUrl.setText(mSearchUrl.get(i));
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
selectedItem = i;
}
});
}
#Override
public int getItemCount() {
return mImages.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView searchUrl;
public ViewHolder(#NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.ivEngine);
searchUrl = itemView.findViewById(R.id.ivEngineText);
}
}
}
And this is the MainActivity.class
public void intSearch() {
mImages.add(R.drawable.s_bing);
mSearchUrl.add("https://www.bing.com/search?q=");
mImages.add(R.drawable.s_google);
mSearchUrl.add("https://www.google.com/search?q=");
mImages.add(R.drawable.s_yahoo);
mSearchUrl.add("www.yahoo.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
initRecyclerView();
}
private void initRecyclerView() {
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = findViewById(R.id.lvEngines);
recyclerView.setLayoutManager(layoutManager);
ListViewAdapter adapter = new ListViewAdapter(mImages, mSearchUrl, this);
recyclerView.setAdapter(adapter);
}
Initialize your selected item globally
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder>{
private int selectedItem = 0;
.....
Then inside your onBindViewHolder whenever you click a new Image notify your adapter for changes in the last selected item cell.
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int previousSelectedItem = selectedItem;
selectedItem = i;
notifyItemChanged(previousSelectedItem);
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}
});
Just remove this line from onBindViewHolder
selectedItem = 0;
and add an else to the background condition, like:
if (selectedItem == i) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}else{
viewHolder.image.setBackgroundColor(“YOUR_DEFAULT_COLOR”);
}
and update the onClick:
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedItem = i;
notifyDataSetChanged();
}
});
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
[Code below] Item in RecycleView doesn't click [it should open the DetailActivity], I try to find the mistake but I didn't understand where
What I try :
Change size items
Change RecycleView to VERTICAL
Write Log.v
I have the same RecycleViewAdapter but it vertical, and it is working well.
my all project : https://github.com/sanke46/E-Commerce
RecycleViewAdapter :
public class SalesRecyclerViewAdapter extends RecyclerView.Adapter<SalesRecyclerViewAdapter.ViewHolder> {
BasketActivity basketActivity = new BasketActivity();
private List<Item> itemList = basketActivity.getBasketItem();
private ArrayList arr;
private Context mContext;
public SalesRecyclerViewAdapter(Context context, ArrayList<Item> data) {
this.arr = data;
mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_sale, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Item item = (Item) arr.get(position);
Picasso.with(mContext).load(item.getImageUrl()).into(holder.imageView);
holder.price.setText(item.getPrice() + " $");
holder.price.setPaintFlags(holder.price.getPaintFlags()| Paint.STRIKE_THRU_TEXT_FLAG);
holder.fixPrice.setText(item.getDiscontPrice() + " $");
holder.name.setText(item.getName());
holder.comment.setText(item.getComment());
holder.gramm.setText(item.converGramms(String.valueOf(item.getGramms())));
holder.kal.setText(item.getKalories() + " kal");
holder.addToCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
itemList.add((Item) arr.get(position));
basketActivity.setBasketItem(itemList);
}
});
holder.linerSaleClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(mContext, DetailActivity.class);
intent.putExtra("item", item);
mContext.startActivity(intent);
Log.v("SALES", "SALES");
}
});
}
#Override
public int getItemCount() {
return arr.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private RelativeLayout linerSaleClick;
private ImageView imageView;
private TextView price;
private TextView fixPrice;
private TextView name;
private TextView comment;
private TextView gramm;
private TextView kal;
private Button addToCart;
public ViewHolder(View itemView) {
super(itemView);
linerSaleClick = itemView.findViewById(R.id.linerSaleClick);
imageView = itemView.findViewById(R.id.imageSale);
price = itemView.findViewById(R.id.price);
kal = itemView.findViewById(R.id.kal);
gramm = itemView.findViewById(R.id.gramm);
name = itemView.findViewById(R.id.name);
comment = itemView.findViewById(R.id.comments);
fixPrice = itemView.findViewById(R.id.fixPrice);
addToCart = itemView.findViewById(R.id.buttonTwo);
}
}}
Basically code on your github is different than what you posted. So probably the reason of problem is:
In list_sale.xml
I noticed that in this view com.makeramen.roundedimageview.RoundedImageView you set parametr android:clickable="true" then if you want to rise click event on parent (RelativeLayout) it will not work. Solution: remove this line android:clickable="true".