How to get the number of Items in multiple Spinner View and calculate the total price

人走茶凉 提交于 2019-12-03 20:06:57

I just update your code without creating new. First I will answer the three questions.

  1. The spinners are resetting after scrolled because the adapter call getView() method and they are initializing to default value again. To avoid this and get back your previously selected values, what you have to do is save them in a map and assign back. In following code "selectedItem" is the map I used to store selected amounts for each spinner.
  2. To get total amount you can use another map which is used to store total price of each spinner. In the following code I used "totalPrices" for it. Inside onItemSelected() we can put total amount for specific spinner. Inside the onclick() method of "BUY" button you can access this map by calling getTotalPrice() method is adapter class.
  3. This is quiet easy. We don't have to get separate array. We can get this information using "selectedItem" map which used to store selected values of spinners. Same as the total price, you can get this map using getTotalItems().

Also in your price calculation inside onItemSelected() method you used "i" to multiply the item price. It should be (i+1). Because "i" is the position of the list in spinner. It starts from 0.

This is the Base_Adapter class

public class Base_Adapter extends BaseAdapter{

    ImageView image;
    TextView name, price;

    private HashMap<Integer,Integer> selectedItem=new HashMap<Integer, Integer>();
    private HashMap<Integer, String> totalPrices=new HashMap<Integer, String>();

    Context context ;
    ArrayList<ItemDetails> IDetails; //The item class which have methods and fields
    RelativeLayout R_Layout;
    Activity activit;


    public Base_Adapter(Context context , ArrayList<ItemDetails> li) {
        // TODO Auto-generated constructor stub
        this.context = context;
        IDetails = li;

    }

    public void setLayout(Activity activity, RelativeLayout layout){
        R_Layout = layout;
        this.activit = activity;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return IDetails.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    public HashMap<Integer,Integer> getTotalItems(){
        return selectedItem;
    }

    public HashMap<Integer, String> getTotalPrice(){
        return totalPrices;
    }

    //////// Get View For Spinner////
    @Override
    public View getView(final int position, View CV, ViewGroup parent) {
        // TODO Auto-generated method stub

        final ItemDetails item = IDetails.get(position);
        int min =1;
        int max = Integer.parseInt(item.stock());



        LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView=inflater.inflate(R.layout.base_adapter, parent,false);

        ArrayList<String> A_list= new ArrayList<String>();

        for(int i=1;i<=max;i++)
        {
            A_list.add("Number of Items :"+i);
        }


        ImageView image=(ImageView) rowView.findViewById(R.id.item_image);


        TextView nameTextView=(TextView) rowView.findViewById(R.id.item_name);
        nameTextView.setText(item.title());

        final TextView price=(TextView) rowView.findViewById(R.id.item_price);

        Spinner quantity=(Spinner) rowView.findViewById(R.id.items);

        ArrayAdapter<String > quatity=new ArrayAdapter<String>(context, R.layout.spinner_textview, R.id.item_list, A_list);
        quantity.setAdapter(quatity);


        if(selectedItem.get(position) != null){
            //This should call after setAdapter
            quantity.setSelection(selectedItem.get(position));
        }

        quantity.setOnItemSelectedListener(new OnItemSelectedListener()
        {

            public void onItemSelected(AdapterView<?> arg0, View arg1, int i, long arg3)
            {


                if(i>0){
                    selectedItem.put(position, i);

                    i=i+1;
                    float cal=Float.parseFloat(item.price());

                    float cal3=cal*i;
                    price.setText(""+String.format("%.2f", cal3).replace(".", ","));

                    item.Totalprice= cal3;
                }
                else{
                    price.setText(""+String.format("%.2f", Float.parseFloat(item.price())).replace(".", ","));

                }
                totalPrices.put(position, price.getText().toString());

            }

            public void onNothingSelected(AdapterView<?> arg0){

            }

        });

        return rowView;

    }
}

So inside your activity class implement onclick method for the "BUY" button.

public void getTotal(View view){
    HashMap<Integer, Integer>totalItems=adapter.getTotalItems();
    HashMap<Integer, String> totalPrices=adapter.getTotalPrice();
    for(int i=0;i<totalItems.size();i++){
        if(totalItems.get(i) != null){
        System.out.println("Spinner No"+(i+1)+"Items :"+(totalItems.get(i)+1));
        System.out.println("Spinner No "+(i+1)+"total price "+totalPrices.get(i));
        }else{
            System.out.println("Spinner No"+(i+1)+"Items : 1");
        }
    }

U need something like badge(selected quantity) * the mrp which will give total amount

For reference https://developer.android.com/training/contacts-provider/display-contact-badge.html

Brace yourself, this answer got long.

You already have a class, IDetails, that describes the items up for sale. I'll suggest a slightly different approach, but if you don't like it, jump to The Adapter-section. I will however use my altered models throughout this answer, as they make stuff easier for some of your questions.


The models

Create a base class that describes an item. We'll make this class abstract and extend on it to describe the individual items you sell.

public abstract class ShoppingItem {

    /* You can add more fields here, for example an image */

    protected String title;
    protected String description;

    protected int cost;

    // Each object keeps track of how many of itself is being bought
    protected int numberBought = 1;

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    public int getCost() {
        return cost;
    }
    public void setCost(int cost) {
        this.cost = cost;
    }

    public int getNumberBought() {
        return numberBought;
    }

    public void setNumberBought(int numberBought) {
        this.numberBought = numberBought;
    }   
}

Individual items can now easily be created:

public class Banana extends ShoppingItem {
    public Banana() {
        this.title = "Banana";
        this.description = "A tasty banana";
        this.cost = 100;
    }
}   

public class Apple extends ShoppingItem {
    public Apple() {
        this.title = "Apple";
        this.description = "A fresh apple";
        this.cost = 200;
    }
}


The Adapter

Now that we have the models all sorted out, how do we populate a ListView with them in the most effienct way? With a custom Adapter, just like you did. We'll fix the spinners resetting when scrolling, and we will also add some nifty performance enhancements.

public class ShoppingAdapter extends ArrayAdapter<ShoppingItem> {

    // We use this LayoutInflater to inflate the xml for each row in the list
    private LayoutInflater mInflater;

    // This is the strings that will populate the spinners
    // Can be moved to res/values/string-array.xml to prevent hardcoded strings
    private String[] spinnerArray = new String[] { "No. items: 1", 
                                                   "No. items: 2",
                                                   "No. items: 3",
                                                   "No. items: 4"};

    public ShoppingAdapter(Context context, int resource, ArrayList<ShoppingItem> objects) {
        super(context, 0, objects);

        // Initialize the declared LayoutInflater 
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        // This is a simple reference holding class, so we don't have to call
        // findViewById() every time getView() is called. Improved performance :)
        ViewHolder holder = null;

        if(convertView == null) { 
            // If convertView is null, then we don't have a view to place
            // our data in. We have to inflate one ourself
            convertView = mInflater.inflate(R.layout.list_item, null);

            // Store a reference to the Spinner and the TextView in 
            // the ViewHolder object
            holder = new ViewHolder();          
            holder.spinner = (Spinner) convertView.findViewById(R.id.spinner);
            holder.textView = (TextView) convertView.findViewById(R.id.total);

            // Attach the ViewHolder object to convertView, as a tag
            convertView.setTag(holder);
        }
        else {
            // If convertView is non-null then we can fetch the ViewHolder object
            // we stored in the tag earlier. We now have references to both the Spinner 
            // and TextView, through the ViewHolder object.
            holder = (ViewHolder) convertView.getTag();
        }

        // If the holder is non-null, we are good to go!
        if(holder != null) {
            // Fetch the item from the underlying ArrayList
            final ShoppingItem item = getItem(position);

            // We need this to be final, so we can access it inside the 
            // onItemSelected()-callback
            final TextView textview = holder.textView;

            // Populate the Spinner
            holder.spinner.setAdapter(new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, spinnerArray));

            // Add a callback when an item is selected in the Spinner
            holder.spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> adapterView, View v, int pos, long id) {
                    // Spinner position is 0-based, so we have to increment 
                    // by one
                    item.setNumberBought(pos + 1);  

                    // Update the total amount in the TextView
                    textview.setText(Integer.toString(item.getCost() * item.getNumberBought()));
                }

                @Override
                public void onNothingSelected(AdapterView<?> arg0) {} // We don't care
            });

            // Set the spinner to the correct position
            // By asking the underlying item how many is bought,
            // the spinner will always show the correct number.
            holder.spinner.setSelection(getItem(position).getNumberBought()-1);
        }   

        return convertView;
    }

    // This guys job is to hold references to the 
    // views we need to access in each row
    private static class ViewHolder {
        public Spinner spinner;
        public TextView textView;
    }
}


How to use it

public class MainActivity extends ListActivity {

    private ShoppingAdapter mAdapter;
    private ArrayList<ShoppingItem> items;

    @SuppressWarnings("unchecked")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // If savedInstanceState is null, then we have a "fresh" start.
        // Create the 
        if(savedInstanceState == null) {
            items = new ArrayList<ShoppingItem>();
            items.add(new Banana());
            items.add(new Apple());
            items.add(new Banana());
            items.add(new Apple());
            items.add(new Banana());
            items.add(new Apple());
            items.add(new Banana());
        }
        // If savedInstanceState is non-null, we should be able to fetch 
        // the list of items
        else {
            items = (ArrayList<ShoppingItem>) savedInstanceState.getSerializable("items");
        }

        mAdapter = new ShoppingAdapter(this, 0, items);

        getListView().setAdapter(mAdapter);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        // We have to keep our ListView persistent through screen rotations.
        // Lets store the list of items in the "savedInstanceState" Bundle.
        outState.putSerializable("items", items);
    }
}

Getting all the metadata you wanted, like total cost, total number of products, etc is easy.

@Override
public void onClick(View v) {
    int totalCost = 0;
    int numBananas = 0;
    int numApples = 0;

    int totalNum = mItems.size();

    for(ShoppingItem item : mItems) {
        int numberBought = item.getNumberBought();

        totalCost += item.getCost() * numberBought;

        if(item instanceof Banana) {
            numBananas += numberBought;
        }
        else if(item instanceof Apple) {
            numApples += numberBought;
        }
        // etc, etc
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!