从删除按钮上的ListView中删除项目时应用程序崩溃单击

时间:2016-01-29 21:45:03

标签: android listview arraylist notifydatasetchanged

我很难解决我的代码问题。

当按ListView项中的删除按钮时,理想情况下应该删除该项,并在调用notifyDataSetChanged()时刷新列表视图;

然而,情况并非如此,在从填充ListView的基础ArrayList中删除项目后调用此方法,导致应用程序崩溃。

此外,作为数据源的上述ArrayList存在于扩展Application的Activity中,允许通过app全局访问数据源。

以下是我的代码。任何帮助将不胜感激。

public class CartListAdapter extends ArrayAdapter<Product> {

    private ArrayList<Product> products;

    //Application context where ArrayList exists for globabal access
    final Global globalVariables = (Global) getContext().getApplicationContext();


    public CartListAdapter(Context context, int textViewResourceId, ArrayList<Product> products ) {
        super(context, textViewResourceId, products);

        this.products=products;
    }

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

        View row = convertView;
        prodHolder mainHolder;
         final int pos=position;
        if(row == null)
        {

            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(R.layout.activity_cart_row_item, parent, false);
//create holders for listview items
        final prodHolder holder = new prodHolder();
            holder.txtName = (TextView) row.findViewById(R.id.cart_product_name);
            holder.txtAmount= (TextView) row.findViewById(R.id.cart_product_price);
            holder.txtQuantity=(TextView) row.findViewById(R.id.cart_quantity_text);
            holder.txtRestaurant= (TextView) row.findViewById(R.id.cart_restaurant);
            holder.txtType = (TextView) row.findViewById(R.id.cart_type);
            holder.txtOption  = (TextView) row.findViewById(R.id.cart_option);
            holder.plus = (Button) row.findViewById(R.id.cart_increment_quantity);
            holder.minus = (Button) row.findViewById(R.id.cart_decrement_quantity);
            holder.delete = (Button) row.findViewById(R.id.cart_delete_button);

            holder.delete.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {

                   globalVariables.getGlobalProductArrayList().remove(position);
                    CartListAdapter.this.notifyDataSetChanged();

                }
            });
//when clicking the plus button in the cart on an item, the cart changes accordingly
            holder.plus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //change quantity when increment button pressed
                    String quantityTextValue= (String) holder.txtQuantity.getText();
                    int quantityConvertedInt = Integer.parseInt(quantityTextValue);
                    int newQuantity= quantityConvertedInt+1;
                    holder.txtQuantity.setText(newQuantity+"");
                    //change total amount when increment button pressed
                    String amountTextValue = (String) holder.txtAmount.getText();
                    int  amountConvertedInt = Integer.parseInt(amountTextValue);
                    int pricePerItem = amountConvertedInt/quantityConvertedInt;
                    int newPrice = amountConvertedInt+pricePerItem;
                    holder.txtAmount.setText(newPrice+"");

                    //get textviews from holders
                    Product product = new Product("", 0, 0, "", "", "");

                    String name = (String) holder.txtName.getText();
                    String price = (String) holder.txtAmount.getText();
                    String quantity = (String) holder.txtQuantity.getText();
                    String restaurant = (String) holder.txtRestaurant.getText();
                    String mealType = (String) holder.txtType.getText();
                    String option = (String) holder.txtOption.getText();
                    //set attributes of temporary product
                    product.setProductName(name);
                    product.setProductPrice(Integer.parseInt(price));
                    product.setProductQuantity(Integer.parseInt(quantity));
                    product.setRestaurant(restaurant);
                    product.setProductType(mealType);
                    product.setProductOption(option);

                    int cartLength = globalVariables.getMyProductsSize();

                    //loop through arraylist that exists in global context
                    for ( int i = 0; i < cartLength; i++) {
                        Product p = globalVariables.getMyProducts(i);

                        //if temporary product attributes match the attributes of product in arraylist

                        if (product.getProductName().equals(p.getProductName())
                                && product.getProductType().equals(p.getProductType())
                                && product.getProductOption().equals(p.getProductOption()))
                        //update that products attributes with the new quantity and total price so
                        // that listview does not refresh values
                        {
                            p.setProductQuantity(product.getProductQuantity());
                            p.setProductPrice(product.getProductPrice());
                        }

                    }

                }
            });


            row.setTag(holder);

        }

        mainHolder = (prodHolder) row.getTag();


        //get product stored in array that exists in Application class
        Product p = globalVariables.getMyProducts(position);


        mainHolder.txtName.setText(p.getProductName());
        mainHolder.txtAmount.setText(p.getProductPrice()+"");
        mainHolder.txtQuantity.setText(p.getProductQuantity()+"");
        mainHolder.txtRestaurant.setText(p.getRestaurant());
        mainHolder.txtType.setText(p.getProductType());
        mainHolder.txtOption.setText(p.getProductOption());

        return row;

    }

}

扩展ArrayList的Global类......

public class Global extends Application {


    //holds an array of products throughout application life cycle
    private ArrayList <Product> myProducts = new ArrayList<>();
    //not in use
    private Cart cart;


    public Cart getCart() {

        return cart;
    }

    public void setCart(Cart cart) {

        this.cart = cart;
    }


    public ArrayList <Product> getGlobalProductArrayList(){

        return this.myProducts;
    }

    public void removeItem (int position){

        myProducts.remove(position);
    }


//gets the products in the arraylist at the specified position
    public Product getMyProducts(int position) {
        return myProducts.get(position);
    }
//adds a product to the array
    public void addMyProducts(Product product) {
        myProducts.add(product);
    }
//get the size of the array, the amount of products in an array
    public int getMyProductsSize (){
        return myProducts.size();
    }

}

...堆栈跟踪

01-29 23:40:13.992 28953-28953/za.co.clickandeat.clickeatbeta W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x415c0d88)
01-29 23:40:13.992 28953-28953/za.co.clickandeat.clickeatbeta E/test: Exception
01-29 23:40:14.032 28953-28953/za.co.clickandeat.clickeatbeta E/AndroidRuntime: FATAL EXCEPTION: main 
Process: za.co.clickandeat.clickeatbeta, PID: 28953   java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) 
at java.util.ArrayList.get(ArrayList.java:308)
at za.co.clickandeat.clickeatbeta.Global.getMyProducts(Global.java:43) 
at za.co.clickandeat.clickeatbeta.CartListAdapter.getView(CartListAdapter.java:147)    at android.widget.AbsListView.obtainView(AbsListView.java:2240) 
at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)  
at android.widget.ListView.onMeasure(ListView.java:1175)
at android.view.View.measure(View.java:16643)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)   
at android.view.View.measure(View.java:16643)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16643)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:16643)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16643)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16643)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125) 
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16643)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2298)
at android.view.View.measure(View.java:16643)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1916)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1113)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1295)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5675)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5214)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:814)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:630)
at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

您应该在数组适配器上调用remove()方法。该参数是要删除的Product对象。

 func updateColor()
{
    let circle = UIView(frame: CGRect(x: -25.0, y: 10.0, width: 100.0,    height: 100.0))
    circle.layer.cornerRadius = 50.0;
    let startingColor = UIColor(red: (CGFloat(redd1))/255, green: (CGFloat(greenn1))/255, blue: (CGFloat(bluee1))/255, alpha: 1.0)
    circle.backgroundColor = startingColor;
    addSubview(circle);
    //print(redd1);
}

像这样执行删除可确保适配器知道已删除的项目,并通知自己已更改某些内容,从而更新适配器的所有属性。