android Spinner getSelection 在 android studio 中出错

android Spinner getSelection is giving error in android studio

我正在尝试将 firebase 实时数据库添加到我的购物车片段中,我希望当有人点击结账按钮时,他们应该被重定向到结账 activity 并且他订购的产品应该进入 firebase 数据库没有错误,但是当我 运行 应用程序时。应用程序关闭并且在 log cat 中出现此错误。

LogCat

2021-04-07 05:14:29.398 8294-8294/com.example.naashtae E/xample.naashta: [qarth_debug:]  get PatchStore::createDisableExceptionQarthFile method fail.
    
    --------- beginning of crash
2021-04-07 05:14:29.400 8294-8294/com.example.naashtae E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.naashtae, PID: 8294
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Spinner.setSelection(int, boolean)' on a null object reference
        at com.example.shoppingcart.models.CartItem.getSelectedSpinnerValue(CartItem.java:54)
        at com.example.shoppingcart.views.CartFragment.confirm(CartFragment.java:138)
        at com.example.shoppingcart.views.CartFragment.onClick(CartFragment.java:116)
        at android.view.View.performClick(View.java:6659)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View.performClickInternal(View.java:6631)
        at android.view.View.access00(View.java:790)
        at android.view.View$PerformClick.run(View.java:26187)
        at android.os.Handler.handleCallback(Handler.java:907)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7625)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

CartFragment.java

package com.example.shoppingcart.views;

import android.content.Intent; import android.os.Bundle;



import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.databinding.BindingAdapter; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.recyclerview.widget.DividerItemDecoration;

import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView;

import com.example.shoppingcart.R; import com.example.shoppingcart.adapters.CartListAdapter; import com.example.shoppingcart.cartholder; import com.example.shoppingcart.databinding.FragmentCartBinding; import com.example.shoppingcart.models.CartItem; import com.example.shoppingcart.viewmodels.ShopViewModel; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.firestore.FirebaseFirestore;

import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.List; import java.util.UUID;

public class CartFragment extends Fragment implements CartListAdapter.CartInterface {

    private static final String TAG = "CartFragment";
    FirebaseFirestore firebaseFirestore;
    public TextView productprice;
    public Spinner productquantity;
    Spinner spinner;
    int quantity;
    ShopViewModel shopViewModel;
    FragmentCartBinding fragmentCartBinding;
    NavController navController;
    Button button;





    private void finishActivity() {
        if (getActivity() != null) {
            getActivity().finish();
        }
    }

    public CartFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {



        // Inflate the layout for this fragment
         fragmentCartBinding = FragmentCartBinding.inflate(inflater, container, false);
        firebaseFirestore = FirebaseFirestore.getInstance();
        return fragmentCartBinding.getRoot();



    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);


        navController = Navigation.findNavController(view);

        final CartListAdapter cartListAdapter = new CartListAdapter(this);
        fragmentCartBinding.cartRecyclerView.setAdapter(cartListAdapter);
        fragmentCartBinding.cartRecyclerView.addItemDecoration(new DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL));

        shopViewModel = new ViewModelProvider(requireActivity()).get(ShopViewModel.class);
        shopViewModel.getCart().observe(getViewLifecycleOwner(), new Observer<List<CartItem>>() {
            @Override
            public void onChanged(List<CartItem> cartItems) {
                cartListAdapter.submitList(cartItems);
                fragmentCartBinding.placeOrderButton.setEnabled(cartItems.size() > 0);
            }
        });

        shopViewModel.getTotalPrice().observe(getViewLifecycleOwner(), new Observer<Double>() {
            @Override
            public void onChanged(Double aDouble) {
                fragmentCartBinding.orderTotalTextView.setText("Total: PKR " + aDouble.toString());
                String price=aDouble.toString().trim();
            }
        });

        button = (Button) getView().findViewById(R.id.placeOrderButton);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                confirm();

            }
        });
    }

    public void confirm() {
        productprice = getView().findViewById(R.id.orderTotalTextView);


        final String saveCurrentDate, saveCurrentTime;

        Calendar calForDate = Calendar.getInstance();
        SimpleDateFormat currentDate = new SimpleDateFormat("MMM dd, yyyy");
        saveCurrentDate = currentDate.format(calForDate.getTime());

        SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss a");
        saveCurrentTime = currentTime.format(calForDate.getTime());



        String productPrice = productprice.toString().trim();
        String productq= CartItem.getSelectedSpinnerValue(spinner,quantity).trim();

        UUID uuid = UUID.randomUUID();
        String randomUUIDString = uuid.toString().trim();

        cartholder op = new cartholder(productPrice,productq, saveCurrentDate, saveCurrentTime);

        FirebaseDatabase dab = FirebaseDatabase.getInstance();
        DatabaseReference note = dab.getReference(randomUUIDString);

        note.child("Products").setValue(op);


        Intent intent = new Intent(CartFragment.this.getActivity(), CheckoutActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finishActivity();
    }


    @Override
    public void deleteItem(CartItem cartItem) {
        shopViewModel.removeItemFromCart(cartItem);
    }

    @Override
    public void changeQuantity(CartItem cartItem, int quantity) {
        shopViewModel.changeQuantity(cartItem, quantity);
    }



    }

fragment_cart.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:orientation="vertical"
        tools:context=".views.CartFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/cartRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/cart_row"
            tools:itemCount="2"
            />

        <Space
            android:layout_width="match_parent"
            android:layout_height="16dp" />

        <TextView
            android:id="@+id/orderTotalTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:layout_margin="8dp"
            android:text="Total: PKR 26"
            android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />

        <Button
            android:id="@+id/placeOrderButton"
            style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:layout_margin="8dp"
            android:text="Proceed To Checkout"
            android:textAppearance="@style/TextAppearance.MaterialComponents.Caption" />

    </LinearLayout>
</ScrollView>

CartItem.java

package com.example.shoppingcart.models;

import android.widget.Spinner;

import androidx.annotation.NonNull;
import androidx.databinding.BindingAdapter;
import androidx.recyclerview.widget.DiffUtil;

public class CartItem {

    private Product product;
    private int quantity;

    public CartItem(Product product, int quantity) {
        this.product = product;
        this.quantity = quantity;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    @Override
    public String toString() {
        return "CartItem{" +
                "product=" + product +
                ", quantity=" + quantity +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CartItem cartItem = (CartItem) o;
        return getQuantity() == cartItem.getQuantity() &&
                getProduct().equals(cartItem.getProduct());
    }

    @BindingAdapter("android:setVal")
    public static String getSelectedSpinnerValue(Spinner spinner, int quantity) {
        spinner.setSelection(quantity - 1, true);
        return spinner.getSelectedItem().toString();
    }

    public static DiffUtil.ItemCallback<CartItem> itemCallback = new DiffUtil.ItemCallback<CartItem>() {
        @Override
        public boolean areItemsTheSame(@NonNull CartItem oldItem, @NonNull CartItem newItem) {
            return oldItem.getQuantity() == newItem.getQuantity();
        }

        @Override
        public boolean areContentsTheSame(@NonNull CartItem oldItem, @NonNull CartItem newItem) {
            return oldItem.equals(newItem);
        }
    };

}

carthoder.java

package com.example.shoppingcart;

public class cartholder {
    String productPrice,productq,Time,Date;

    public cartholder( String productPrice,String productq, String time, String date) {
        this.productPrice = productPrice;
        this.productq=productq;
        Time = time;
        Date = date;
    }


    public String getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(String productPrice) {
        this.productPrice = productPrice;
    }

    public String getProductq() {
        return productq;
    }

    public void setProductq(String productq) {
        this.productq = productq;
    }

    public String getTime() {
        return Time;
    }

    public void setTime(String time) {
        Time = time;
    }

    public String getDate() {
        return Date;
    }

    public void setDate(String date) {
        Date = date;
    }
}

CartRepo.java

package com.example.shoppingcart.repositories;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.example.shoppingcart.models.CartItem;
import com.example.shoppingcart.models.Product;

import java.util.ArrayList;
import java.util.List;

public class CartRepo {

    private MutableLiveData<List<CartItem>> mutableCart = new MutableLiveData<>();
    private MutableLiveData<Double> mutableTotalPrice = new MutableLiveData<>();

    public LiveData<List<CartItem>> getCart() {
        if (mutableCart.getValue() == null) {
            initCart();
        }
        return mutableCart;
    }

    public void initCart() {
        mutableCart.setValue(new ArrayList<CartItem>());
        calculateCartTotal();
    }

    public boolean addItemToCart(Product product) {
        if (mutableCart.getValue() == null) {
            initCart();
        }
        List<CartItem> cartItemList = new ArrayList<>(mutableCart.getValue());
        for (CartItem cartItem: cartItemList) {
            if (cartItem.getProduct().getId().equals(product.getId())) {
                if (cartItem.getQuantity() == 5) {
                    return false;
                }

                int index = cartItemList.indexOf(cartItem);
                cartItem.setQuantity(cartItem.getQuantity() + 1);
                cartItemList.set(index, cartItem);

                mutableCart.setValue(cartItemList);
                calculateCartTotal();
                return true;
            }
        }
        CartItem cartItem = new CartItem(product, 1);
        cartItemList.add(cartItem);
        mutableCart.setValue(cartItemList);
        calculateCartTotal();
        return true;
    }

    public void removeItemFromCart(CartItem cartItem) {
        if (mutableCart.getValue() == null) {
            return;
        }
        List<CartItem> cartItemList = new ArrayList<>(mutableCart.getValue());
        cartItemList.remove(cartItem);
        mutableCart.setValue(cartItemList);
        calculateCartTotal();
    }

    public  void changeQuantity(CartItem cartItem, int quantity) {
        if (mutableCart.getValue() == null) return;

        List<CartItem> cartItemList = new ArrayList<>(mutableCart.getValue());

        CartItem updatedItem = new CartItem(cartItem.getProduct(), quantity);
        cartItemList.set(cartItemList.indexOf(cartItem), updatedItem);

        mutableCart.setValue(cartItemList);
        calculateCartTotal();
    }

    private void calculateCartTotal() {
        if (mutableCart.getValue() == null) return;
        double total = 0.0;
        List<CartItem> cartItemList = mutableCart.getValue();
        for (CartItem cartItem: cartItemList) {
            total += cartItem.getProduct().getPrice() * cartItem.getQuantity();
        }
        mutableTotalPrice.setValue(total);
    }

    public LiveData<Double> getTotalPrice() {
        if (mutableTotalPrice.getValue() == null) {
            mutableTotalPrice.setValue(0.0);
        }
        return mutableTotalPrice;
    }

}

CartListAdapter.java

package com.example.shoppingcart.adapters;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;

import com.example.shoppingcart.databinding.CartRowBinding;
import com.example.shoppingcart.models.CartItem;

public class CartListAdapter extends ListAdapter<CartItem, CartListAdapter.CartVH> {

    private CartInterface cartInterface;
    public CartListAdapter(CartInterface cartInterface) {
        super(CartItem.itemCallback);
        this.cartInterface = cartInterface;
    }

    @NonNull
    @Override
    public CartVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        CartRowBinding cartRowBinding = CartRowBinding.inflate(layoutInflater, parent, false);
        return new CartVH(cartRowBinding);
    }

    @Override
    public void onBindViewHolder(@NonNull CartVH holder, int position) {
        holder.cartRowBinding.setCartItem(getItem(position));
        holder.cartRowBinding.executePendingBindings();
    }

    class CartVH extends RecyclerView.ViewHolder {

        CartRowBinding cartRowBinding;
        public CartVH(@NonNull CartRowBinding cartRowBinding) {
            super(cartRowBinding.getRoot());
            this.cartRowBinding = cartRowBinding;

            cartRowBinding.deleteProductButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    cartInterface.deleteItem(getItem(getAdapterPosition()));
                }
            });

            cartRowBinding.quantitySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    int quantity = position + 1;
                    if (quantity == getItem(getAdapterPosition()).getQuantity()) {
                        return;
                    }
                    cartInterface.changeQuantity(getItem(getAdapterPosition()), quantity);
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {

                }
            });
        }
    }

    public interface CartInterface {
        void deleteItem(CartItem cartItem);
        void changeQuantity(CartItem cartItem, int quantity);
    }
}

logcat 告诉你在 CartItem.java:54

中有一个 null object reference

这个方法

public static String getSelectedSpinnerValue(Spinner spinner, int quantity) {
    spinner.setSelection(quantity - 1, true);
    return spinner.getSelectedItem().toString();
}
当您从 CartFragment.confirm(CartFragment.java:138)

调用它时,

得到一个空微调器

String productq= CartItem.getSelectedSpinnerValue(spinner,quantity).trim();

那是因为 spinner 为空,您从未使用过 spinner = findViewById(R.id.spinner); 或类似的东西。