I can remove the item in holder but the price doesn't exchange. i had try to make the data remove but it's non sense too
i had try make the sub been minus but's still it's doesn't work on it i had the for list on the holder to made the price exchange it doesn't help through too
One Fragment.java
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View krnjg =inflater.inflate(R.layout.fragment_keranjang,container,false);
RecyclerView rec = krnjg.findViewById(R.id.rc1);
LinearLayoutManager aw1 =new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false);
rec.setLayoutManager(aw1);
madapter = new ProductAdapter(getContext(), example, getLayoutInflater());
rec.setAdapter(madapter);
madapter.notifyDataSetChanged();
total = krnjg.findViewById(R.id.vtotal);
btnpesan = krnjg.findViewById(R.id.btnpsn);
for (int i = 0;i < example.size();i++){
sub = sub + example.get(i).getPrice();
}
Locale locale = new Locale("in","ID");
NumberFormat formatrupiah = NumberFormat.getCurrencyInstance(locale);
total.setText(formatrupiah.format(sub));
Product adapter.java
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, final int position) {
Locale locale = new Locale("in","ID");
NumberFormat formatrupiah = NumberFormat.getCurrencyInstance(locale);
holder.nmPro.setText(mData.get(position).getTitle());
holder.imge.setImageResource(mData.get(position).getProductImage());
holder.hrg.setText(formatrupiah.format(mData.get(position).getPrice()));
holder.cd.setActivated(mData.get(position).selected);
holder.del.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mData.remove(holder.getAdapterPosition());
double sub = 0;
for (int i = 1; i<example.size();i++){
sub -= example.get(i).getPrice();
}
notifyDataSetChanged();
Toast.makeText(mCon,"Barang "+holder.nmPro.getText()+" di hapus dari keranjang",Toast.LENGTH_SHORT).show();
}
});
}
i expect that the holder won't worked even the data that was holder it for just on that view not on the fragment that used to handle or maybe another ways to find it out because the total and the recycler is on different fragment that there is on adapter and fragment it's self
I have been solved this I just used a new classes to hold the click and price even I delete the item the price still same, which else item still on there. So this is I used for
public double getTotalPrice() {
double totalPrice = 0;
for (int i = 0; i < mData.size(); ++i) {
totalPrice = totalPrice + mData.get(i).getPrice();
}
return totalPrice;
}
this class to get the total price on adapter and I got the class on holder too. For when I deleted the item the price is still same which item still on there like this I used it for
holder.del.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mData.remove(holder.getAdapterPosition());
notifyDataSetChanged();
tvTotal.setText(formatrupiah.format(getTotalPrice()));
Toast.makeText(mCon,"Barang "+holder.nmPro.getText()+" di hapus dari keranjang",Toast.LENGTH_SHORT).show();
}
});
mData is to get the data product from other activity I inputed and remove is to remove item from the cart and tvTotal is the price whenever the price inputed it can be deleted using this class on holder
Related
I'm adding items to a list in a Recyclerview Adapter via an input dialog. when a user enters a value in a textfield and clicks on submit button, I want the entered value to be added to a list which is declared public in a fragment such that if I go to the fragment and click on showListSize button, I should see the size of the list(in fragment) being greater than 0;
Adding an item to the list in RecyclerView works but the size cannot exceed 1. What could I be doing wrong.
Here is a sample code:
//Adapter, constructor and variables declaration
//on create viewholder
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
List<Item2> valuesList = new ArrayList<Item2>(child.get(groupname));
childSize = valuesList.size();
Log.i("List size", String.valueOf(childSize));
if (childSize > 0){
//final String childText = (String) getChild(groupPosition,position);
final Item2 item = valuesList.get(position);
holder.name.setText(item.getItemName());
//holder.itemImage.setImageResource(Integer.parseInt(item.getImageUrl()));
holder.price.setText(String.valueOf(item.getPrice()));
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.select_quantity);
Button button_submit = dialog.findViewById(R.id.btn_submit);
final EditText edQuantity = dialog.findViewById(R.id.txt_quantity);
edQuantity.setText("0");
button_submit.setOnClickListener(new View.OnClickListener() {
float totalPrice = 0;
#Override
public void onClick(View view) {
String quantity = edQuantity.getText().toString();
totalPrice = Float.parseFloat(quantity) * Float.parseFloat(item.getPrice());
myLocal.add(new CartItem(quantity, item.getItemName(), item.getPrice(),String.valueOf(totalPrice)));
AllProducts myProducts = new AllProducts(); //this is the fragment
myProducts.theSelected.add(new CartItem(quantity,item.getItemName(), item.getPrice(),String.valueOf(totalPrice)));
Log.i("size(Recycler)",String.valueOf(myProducts.theSelected.size())); //this is ok returns 1
dialog.dismiss();
}
});
dialog.show();
AllProducts fragment
public List<CartItem> theSelected = new ArrayList<CartItem>();//list declaration
btnShowListSize.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("list(AllProducts)", String.valueOf(theSelected.size()));//returns 0
}
});
I defined a global ArrayList like this
private List<Items> selectedItems = new ArrayList<>();
Then a method to add items, still in global class
public void addItems(Item item) {
this.selectedItems.add(item);
}
Then in a class somewhere in the project:
final Globals myGlobals = Globals.getInstance();
Item myItem = new Item("var1", "var2", "var3");
myGlobals.addItems(myItem);
I have two recycler views. The first recyclerview is basically a list of data where I can choose an item and its quantity and I am storing this chosen item data into a map. The second one is the list of the selected data. which I am generating from getting the values() from the map. The second one also has similar viewholder and I can change the quantity there also. One the quantity reaches zero I remove the item from the list and try to notifydatasetChanged().
The problem is the removing of an item from the second list is not working properly and the app crashes with error
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
I am using a listener interface on my first Recycler so that when the quantity is changed and the item is added to the map. The adapter of the second recycler is notified of the changes. below is the code i am using to update the second recycler view.
public void updateList(){
mMap = ((UserMainActivity)getActivity()).getItemMap();
inputs.clear();
// adapter.notifyDataSetChanged();
adapter = new MyCartAdapter(inputs,getContext());
cartList.setAdapter(adapter);
for(AllItems t:mMap.values()) {
inputs.add(t);
}
adapter.notifyDataSetChanged();
}
Below is my second recycler view's adapter. Where I am changing the quantities of the selected items.
public class MyCartAdapter extends RecyclerView.Adapter<MyCartAdapter.MyCartViewHolder>{
private List<AllItems> listItems1;
private Context context;
private Typeface typeface;
public MyCartAdapter(List<AllItems> listItems1, Context context) {
this.listItems1 = listItems1;
this.context = context;
}
#NonNull
#Override
public MyCartAdapter.MyCartViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cart_items_layout, parent, false);
return new MyCartViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull final MyCartAdapter.MyCartViewHolder holder, final int position) {
final AllItems orderItem = listItems1.get(position);
holder.setProductImage(orderItem.getImageUrl(),context);
holder.name.setText(orderItem.getName());
String price = String.valueOf(orderItem.getPrice());
holder.price.setText(price);
final HashMap<String, AllItems> items = ((UserMainActivity)context).getItemMap();
holder.counter.setText(orderItem.getQuantity());
holder.add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String quantity = String.valueOf(holder.counter.getText());
int count = Integer.parseInt(quantity)+1;
holder.counter.setText(String.valueOf(count));
String url = orderItem.getImageUrl();
AllItems newitem = new AllItems(orderItem.getName(),orderItem.getComname(),url, String.valueOf(count),orderItem.getWeight,orderItem.getPrice());
((UserMainActivity)context).addItem(orderitemname,newitem);
// notifyItemChanged(position);
}
});
//counter text iitem.textview showing the quantity of the selected item . integer count returns the value of counter text below i am checking if its zero than it simply sets the value to zero and else reduce it and update the map.
holder.minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String counterText = String.valueOf(holder.counter.getText());
int count = Integer.parseInt(counterText);
if (count==0){
holder.counter.setText("0");
}
if (count==1){
holder.counter.setText("0");
AllItems item = items.get(orderItem.getName());
if (item!=null){
String orderit = orderItem.getName();
((UserMainActivity)context).removeItem(orderit);
// here i am removing the value from the list which throws the exception
listItems1.remove(position);
notifyItemRemoved(position);
}
}
if (count>1){
String quantity = String.valueOf(count-1);
holder.counter.setText(quantity);
String orderitemname = orderItem.getName();
String url = orderItem.getImageUrl();
String weight = "100";
long weightl = Long.parseLong(weight);
AllItems newitem = new AllItems(orderItem.getName(),orderItem.getComname(),url, quantity,weight,orderItem.getPrice());
((UserMainActivity)context).addItem(orderitemname,newitem);
// listItems1.set(position, newitem);
// notifyItemChanged(position);
}
}
});
}
#Override
public int getItemCount() {
return listItems1.size();
}
public class MyCartViewHolder extends RecyclerView.ViewHolder {
public TextView name,price,count,comname;
public TextView weight;
LinearLayout add,minus;
TextView counter;
public MyCartViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.ProName);
price = (TextView) itemView.findViewById(R.id.proPrice);
weight = (TextView) itemView.findViewById(R.id.ProWeight);
counter = (TextView) itemView.findViewById(R.id.counter);
add = (LinearLayout) itemView.findViewById(R.id.addLin);
minus= (LinearLayout) itemView.findViewById(R.id.minusLin);
}
public void setProductImage(final String thumb_image, final Context ctx){
productImage = (ImageView) itemView.findViewById(R.id.ProImage);
Picasso.with(ctx).setIndicatorsEnabled(false);
Picasso.with(ctx)
.load(thumb_image)
.networkPolicy(NetworkPolicy.OFFLINE)
.placeholder(R.drawable.basket_b).into(productImage, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(ctx).load(thumb_image).placeholder(R.drawable.basket).into(productImage);
}
});
}
public void setComname(String name){
comname = (TextView)itemView.findViewById(R.id.proComName);
comname.setText(name);
}
}
}
This jumps out at me:
listItems1.remove(position);
notifyItemChanged(position);
The notifyItemChanged() method exists to tell the adapter that the data at the given position has changed, and that the ViewHolder should be re-bound. This is not what you're doing; you're removing an item.
Probably your app is crashing because you're removing the last item in your data set (e.g. position 10) and then telling the adapter that the item at position 10 has changed... but now the maximum position in your data set is 9.
Instead, you should use the notifyItemRemoved() method.
listItems1.remove(position);
notifyItemRemoved(position);
I'm Very new to Java and android... I'm Try to create an ListView using BaseAdapter List being created successfully i have a EditText along with button for each list item but the real problem is when i put some data into editText Field and scroll down to change value of last list item then i go back to the top it refreshes the data to default value it doesn't contain the value which was entered by user before scrolling down
My BaseAdaper Code
class CoustomAdptr extends BaseAdapter{
String[] dates;
Integer[] inventory;
Integer totalrooms;
public CoustomAdptr(RoomFragment roomFragment, String[] dates, Integer[] inventory, Integer totalrooms) {
this.dates = dates;
this.inventory = inventory;
this.totalrooms = totalrooms;
}
#Override
public int getCount() {
return dates.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.inventory_listview,null);
TextView textView = (TextView) view.findViewById(R.id.roomListViewText);
final EditText editText = (EditText) view.findViewById(R.id.roomListInventory);
final Button updateButton = (Button) view.findViewById(R.id.roomListViewInventoryUpdateButton);
if(inventory[i] == 0){
editText.setBackgroundColor(getResources().getColor(R.color.SoldOut));
editText.setTextColor(getResources().getColor(R.color.SoldOutTextColor));
} else if(inventory[i] < totalrooms){
editText.setBackgroundColor(getResources().getColor(R.color.invetory));
editText.setTextColor(getResources().getColor(R.color.invetoryTextColor));
} else if(inventory[i] == totalrooms){
editText.setBackgroundColor(getResources().getColor(R.color.fullInventory));
editText.setTextColor(getResources().getColor(R.color.fullInventoryTextColor));
}
editText.setText(String.valueOf(inventory[i]));
textView.setText(dates[i]);
updateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//String name = editText.getText().toString();
//String name1 = dates[i];
//String name2 = getArguments().getString("room_id");
updateButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_done_black_24dp,0,0,0);
//updateButton.setBackgroundColor(getResources().getColor(R.color.SoldOut));
updateButton.setText("Updated");
updateButton.setEnabled(false);
Toast.makeText(getContext(), "Update Inventory Button Clicked", Toast.LENGTH_LONG).show();
}
});
return view;
}
}
This is How Im Passing Data to My Adapter
JSONObject jObj = parentObject.getJSONObject("success");
JSONObject jObj2 = jObj.getJSONObject("data");
JSONArray arrajson = jObj2.getJSONArray("inventories");
String arrayCount = Integer.toString(arrajson.length());
String[] dates = new String[arrajson.length()];
Integer[] inventory = new Integer[arrajson.length()];
Integer totalrooms = new Integer(jObj2.getInt("total_room"));
for (int i=0; i<arrajson.length();i++){
JSONObject jsonObject = arrajson.getJSONObject(i);
dates[i] = jsonObject.getString("date");
inventory[i] = jsonObject.getInt("inventory");
}
CoustomAdptr coustomAdptr = new CoustomAdptr(RoomFragment.this,dates,inventory,totalrooms);
listView.setAdapter(coustomAdptr);
Help Needed :- I Want to retain same visible and Value of edittext as users enters on scroll up or down... i hope i was able to explain my problem clearly
After clicking a button, save it's state in a boolean array or somewhere else. And inside getView method, check if this button was previously clicked or not then setup your view accordingly.
It would be better if you create a model class for rows.
i made a custom listView having two textViews..for example student name and roll no...
now i want to implement a selection...for example..i will click on few students in the listview and the object should get saved somewhere ...for example:
ClassList.add(new StudentList(99,"student1","code"));
ClassList.add(new StudentList(70,"student2","code"));
ClassList.add(new StudentList(20,"student3","code"));
ClassList.add(new StudentList(30,"student4","code"));
adapter = new StudentListViewAdapter(this, ClassList,"code");
listView.setAdapter(adapter);
now i should be able to set another method for example:
ClassList2=listView.getSelectedStudents();
this should return the selected students..for example if i select student 1,student 2 it should return Student List Objects for both of them so i can access there roll and Code too
And there is another problem...when i deselect it should remove that object from the list..
It would be really helpfull if someone will write a sample code
This is how i do it..but i don't think it is really a good method
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (ItemView == null) {
ItemView = inflater.inflate(R.layout.customvistview_atd, parent, false);
}
//find the hotels to work with
final studentlist currentList = totalClass_list.get(position);
//fill the view
final TextView textview_studentName = (TextView) ItemView.findViewById(R.id.textview_atd_studentName);
textview_studentName.setText((currentList.getName()));
final TextView textview_studentRollno = (TextView) ItemView.findViewById(R.id.textview_atd_studentRollno);
textview_studentRollno.setText((currentList.getRoll_no() + ""));
final CardView cardView = (CardView) ItemView.findViewById(R.id.card_view_atd);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (i = 0; i < presentStudents.size(); i++) {
if (presentStudents.get(i).getMindex() == position) {
System.out.println("m-index : "+presentStudents.get(i).getMindex());
System.out.println("position : "+position);
isChecked = true;
System.out.println("I am in the loop, I am at position: "+i);
me = i;
break;
}
}
if (isChecked) {
presentStudents.remove(me);
isChecked = false;
ColorDrawable[] color = {new ColorDrawable(Color.parseColor("#198b9f")), new ColorDrawable(Color.WHITE)};
TransitionDrawable trans = new TransitionDrawable(color);
cardView.setBackground(trans);
trans.startTransition(1500);
textview_studentName.setTextColor(Color.GRAY);
textview_studentName.setTextColor(Color.GRAY);
//cardView.setBackgroundColor(Color.WHITE);
System.out.println("I am in isChecked");
} else {
presentStudents.add(new tempclass(currentList.getRoll_no(),atdCode,position));
ColorDrawable[] colorCard = {new ColorDrawable(Color.WHITE), new ColorDrawable(Color.parseColor("#198b9f"))};
TransitionDrawable trans = new TransitionDrawable(colorCard);
cardView.setBackground(trans);
trans.startTransition(1500);
textview_studentName.setTextColor(Color.WHITE);
textview_studentName.setTextColor(Color.WHITE);
// cardView.setBackgroundColor(Color.BLUE);
System.out.println("I am in else, making it blue");
}
}
});
you can use this one
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
StudentLists studentList = listView.getItemAtPosition(i);//selected object
adapter.dismiss(); // If you want to close the adapter
}
});
I am creating a shopping cart for my application. I have used RecyclerView and static View in fragment. There is delete button on my RecyclerView item.
RecyclerView.Adapter.java
public class ShoppingCartRecyclerAdapter extends RecyclerView.Adapter<ShoppingCartViewHOlder> {
//
// Other `RecyclerView` adapter's methods
//
#Override
public void onBindViewHolder(final ShoppingCartViewHOlder holder, final int position) {
holder.name.setText(cart.getProductName()); // name
holder.sellingPrice.setText(pricePrefix(cart.getSellingPrice())); // selling price
// Quantity spinner adapter
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(context,
android.R.layout.simple_spinner_item, PRODUCT_QUANTITY);
holder.quantity.setAdapter(spinnerAdapter); // quantity
holder.quantity.setSelection(cart.getQuantity() - 1);
holder.quantity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
int quantity = position + 1;
// selling price as per selected quantity
holder.sellingPrice.setText(pricePrefix(cart.getSellingPrice() * quantity));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// Quantity not selected
Toast.makeText(context, "Quantity not selected", Toast.LENGTH_SHORT).show();
}
});
holder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { // Delete
if (isOnline(context)){
cartService.removeFromOnlineCart(cart.getProductId()); // remove data from server and db.
cartList.remove(position); // remove item from list
notifyItemRemoved(position); // notify list changed
notifyItemRangeChanged(position, getItemCount()); // to delete item in real time
} else {
offlineMessage(context);
}
}
});
}
}
class ShoppingCartViewHOlder extends RecyclerView.ViewHolder {
Spinner quantity;
TextView name, sellingPrice, delete;
public ShoppingCartViewHOlder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.my_cart_list_name); // name
sellingPrice = (TextView) view.findViewById(R.id.my_cart_list_price); // selling price
quantity = (Spinner) view.findViewById(R.id.my_cart_quantity); // quantity
delete = (TextView) view.findViewById(R.id.my_cart_list_delete); // delete
}
}
My Fragment.java
public class MyCartFragment extends Fragment implements View.OnClickListener{
private List<GetShoppingCartBean> shoppingCartList;
private RecyclerView recyclerView;
private ShoppingCartRecyclerAdapter adapter;
private TextView grandAmount;
private double sellGrandPrice = 0; // grand total.
public MyCartFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_my_cart, container, false);
// my other code...
// Grand total amount
grandAmount = (TextView) view.findViewById(R.id.my_cart_list_grand_total);
// Recycler view
recyclerView = (RecyclerView) view.findViewById(R.id.my_cart_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(),
LinearLayoutManager.VERTICAL, false));
// get shopping cart items
webServiceCall();
return view;
}
/** Fetch cart items from server */
private void webServiceCall() {
// My server connector code here to fetch cart items....
// on received response, if JsonArray is not empty
// iterating items for selling price adding it to grand amount.
for(GetShoppingCartBean bean: shoppingCartList){
sellGrandPrice += bean.getSellingPrice();
}
// setting adapter to list view
adapter = new ShoppingCartRecyclerAdapter(getContext(), shoppingCartList,
getActivity().getSupportFragmentManager());
recyclerView.setAdapter(adapter);
// showing total price of all items.
DecimalFormat formatter = new DecimalFormat("#,##,##,##,###.00");
String amount = "Rs. "+ (sellGrandPrice == 0 ? 0 : formatter.format(sellGrandPrice));
grandAmount.setText(amount);
}
Currently I am getting total amount of all products for first time, But if I delete any item from list or update quantity, my total amount did not change. Screen looks similar to below snap, just there is delete button instead of book now.
NOTE: I have omitted some of my code like HttpUrlConnection code in webServiceCall(), RecyclerView.Adapter base methods, etc in this post purposely, to keep post short.
I had both Adapter and Fragment classes in separate files. I merged both class, created private inner Adapter class in Fragment class and a method to recalculate selling price multiplied by quantity and update it in textView inside my quantity setOnItemSelectedListener, on delete listener and on web service call.
private void calculateGrandTotal(List<GetShoppingCartBean> cartBeans){
double total = 0;
for(GetShoppingCartBean cart: cartBeans){
total += (cart.getSellingPriceWithOffer() * cart.getQuantity());
}
String price = grandPriceSuffix(total);
grandAmount.setText(price);
}