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

落花浮王杯 提交于 2019-12-05 04:51:30

问题


I am implementing spinner in a list view (Multiple Spinners) for different products with their images on left and prices on right. User has choice to select number (quantity) of each product.

This work is going in a Class that extends from BaseAdapter according to my needs. In getView of the spinner I set the spinner view.

Now I want:

1) when the user select an Item in a Spinner, the price of that item is calculated as total and the TextView text on the right is set to that total price. Now this is working well, but when I scroll up the list, the Spinner changes its value to the old one (i.e., the value at position 0) not the new one total.

2) The other thing i want to do is to keep all these values that came from different spinners in an array, so that at the end all different spinners values are further calculated as total (at first i was calculating the single product values, say the price of that product is 50$ and the user selected that he want 20 pieces of that product so totall=20x50 ).

3) And one other thing i want is to get the number of items selected in one spinner. And in the same way to keep these numbers of each spinner in another array, so that at the end these all are calculated as total number of all products.

Below is the image and sorry as my question gone too long, but i really want to solve this out. And if you want more things from me to post please do tell me.

When I select Items

When I scroll the screen all values in spinners and the prices in the text views reset to initial position

Here is my code

     public class Base_Adapter extends BaseAdapter
        {
            ImageView image;
            TextView name, price;

            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) 
            {
                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 arg0) {
                // TODO Auto-generated method stub
                return null;
            }

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

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


                LayoutInflater infleter = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                if(CV == null)
                {
                    CV = infleter.inflate(R.layout.base_adapter, null);
                }

                final ItemDetails item = IDetails.get(position);
                int min =1;
                int max = Integer.parseInt(item.totall_Available());
                ArrayList<String> A_list= new ArrayList<String>();

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

                 image = (ImageView) CV.findViewById(R.id.Item_image);
                 name = (TextView) CV.findViewById(R.id.item_name);
                 price = (TextView) CV.findViewById(R.id.item_price);

                final Spinner quantity = (Spinner) CV.findViewById(R.id.items);
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,  R.layout.spinner_textview, A_list);
                quantity.setAdapter(adapter);

                 //String selectedItem = (String) quantity.getSelectedItem();

name.setText(item.name());

                  /// ItemClick/////

                quantity.setOnItemSelectedListener(new OnItemSelectedListener()
            {
                public void onItemSelected(AdapterView<?> arg0, View arg1, int i, long arg3)
                {

                   if(i>0){
     float cal=Float.parseFloat(item.Fisrtprise());

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

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

                public void onNothingSelected(AdapterView<?> arg0){

                }

            });



                return CV;


            }

And this is the IDetails Class

@SuppressWarnings("serial")
public class IDetails implements Serializable
{


    ContentValues colmnValues;  
    private int no_of_items;
    public float Totalprice;


    public IDetails(ContentValues values  ) 
    {
        colmnValues = values;
    }


    public String title() {
        return getValue(colmnValues.get("title"));
    }



    public void setNo_of_items(int no_of_items) {
        this.no_of_items = no_of_items;
    }
    public int getNo_of_items() {
        return no_of_items;
    }


    public void setTotalprice(float Totalprice) {
        this.Totalprice = Totalprice;
    }
    public float getTotalprice() {
        return Totalprice;
    }


    public String imageUrl() {
        return getValue(colmnValues.get("imageUrl"));
    }

    public String pprice() {
        return getValue(colmnValues.get("Realprice"));
    }

    public String stock() {
        return getValue(colmnValues.get("stock"));
    }




    private String getValue(Object obj){
        if(obj == null){
            return "";
        }
        return (String) obj;
    }


}

回答1:


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");
        }
    }



回答2:


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




回答3:


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
    }
}


来源:https://stackoverflow.com/questions/21709115/how-to-get-the-number-of-items-in-multiple-spinner-view-and-calculate-the-total

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!