0

Not sure what was going on, I understand that my SizeModel object is null but I can't figure out which part of the code has an error.

Logcat

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Long com.android.ridefun.Model.SizeModel.getPrice()' on a null object reference
    at com.android.ridefun.ui.fooddetail.FoodDetailFragment.calculateTotalPrice(FoodDetailFragment.java:368)
    at com.android.ridefun.ui.fooddetail.FoodDetailFragment.displayInfo(FoodDetailFragment.java:356)
    at com.android.ridefun.ui.fooddetail.FoodDetailFragment.lambda$onCreateView$3$FoodDetailFragment(FoodDetailFragment.java:197)
    at com.android.ridefun.ui.fooddetail.-$$Lambda$FoodDetailFragment$P7ns469KVlm85g5qkSDfjwtWEhE.onChanged(Unknown Source:4)
    at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
    at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
    at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
    at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
    at com.android.ridefun.ui.fooddetail.FoodDetailViewModel.setFoodModel(FoodDetailViewModel.java:41)
    at com.android.ridefun.ui.fooddetail.FoodDetailFragment$1.lambda$onDataChange$0$FoodDetailFragment$1(FoodDetailFragment.java:299)
    at com.android.ridefun.ui.fooddetail.-$$Lambda$FoodDetailFragment$1$kDzBYjkwuFHevzvZPfWIqjcF4o8.onComplete(Unknown Source:4)

FoodDetailFragment.java

private void displayInfo(FoodModel foodModel) {
    Glide.with(getContext()).load(foodModel.getImage()).into(img_food);
    food_name.setText(new StringBuilder(foodModel.getName()));
    food_description.setText(new StringBuilder(foodModel.getDescription()));
    food_price.setText(new StringBuilder(foodModel.getPrice().toString()));

    if(foodModel.getRatingValue() != null)
        ratingBar.setRating(foodModel.getRatingValue().floatValue());

    ((AppCompatActivity)getActivity())
            .getSupportActionBar()
            .setTitle(Common.selectedFood.getName());

    //Size
    for(SizeModel sizeModel: Common.selectedFood.getSize())
    {
        RadioButton radioButton = new RadioButton(getContext());
        radioButton.setOnCheckedChangeListener((compoundButton, b) -> {
            if(b)
                Common.selectedFood.setUserSelectedSize(sizeModel);
            calculateTotalPrice(); //Update price
        });

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,
                LinearLayout.LayoutParams.MATCH_PARENT,
                1.0f);
        radioButton.setLayoutParams(params);
        radioButton.setText(sizeModel.getName());
        radioButton.setTag(sizeModel.getPrice());

        rdi_group_size.addView(radioButton);

    }

    if(rdi_group_size.getChildCount() > 0)
    {
        RadioButton radioButton = (RadioButton)rdi_group_size.getChildAt(0);
        radioButton.setChecked(true); //Default first select
    }

    calculateTotalPrice();
}

private void calculateTotalPrice() {
    double totalPrice = Double.parseDouble(Common.selectedFood.getPrice().toString()),displayPrice=0.0;

    //Addon
    if(Common.selectedFood.getUserSelectedAddon() != null && Common.selectedFood.getUserSelectedAddon().size() > 0)
        for(AddonModel addonModel : Common.selectedFood.getUserSelectedAddon())
            totalPrice+=Double.parseDouble(addonModel.getPrice().toString());

    //size
    totalPrice += Double.parseDouble(Common.selectedFood.getUserSelectedSize().getPrice().toString());

    displayPrice = totalPrice * (Integer.parseInt(numberButton.getNumber()));
    displayPrice = Math.round(displayPrice*100.0/100.0);

    food_price.setText(new StringBuilder("").append(Common.formatPrice(displayPrice)).toString());
}

@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    //Null
}

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    chip_group_addon.clearCheck();
    chip_group_addon.removeAllViews();

    for(AddonModel addonModel:Common.selectedFood.getAddon())
    {
        if(addonModel.getName().toLowerCase().contains(charSequence.toString().toLowerCase()))
        {
            Chip chip = (Chip)getLayoutInflater().inflate(R.layout.layout_addon_item,null);
            chip.setText(new StringBuilder(addonModel.getName()).append("(+$")
            .append(addonModel.getPrice()).append(")"));
            chip.setOnCheckedChangeListener((compoundButton, b) -> {
                if(b)
                {
                    if (Common.selectedFood.getUserSelectedAddon() == null)
                        Common.selectedFood.setUserSelectedAddon(new ArrayList<>());
                    Common.selectedFood.getUserSelectedAddon().add(addonModel);
                }
            });
            chip_group_addon.addView(chip);
        }
    }
}

@Override
public void afterTextChanged(Editable editable) {

}

FoodViewModel.java

public class FoodDetailFragment extends Fragment implements TextWatcher {

private FoodDetailViewModel foodDetailViewModel;

private Unbinder unbinder;
private android.app.AlertDialog waitingDialog;
private BottomSheetDialog addonBottomSheetDialog;

//View need inflate
ChipGroup chip_group_addon;
EditText edt_search;

@BindView(R.id.img_food)
ImageView img_food;
@BindView(R.id.btnCart)
CounterFab btnCart;
@BindView(R.id.btn_rating)
FloatingActionButton btn_rating;
@BindView(R.id.food_name)
TextView food_name;
@BindView(R.id.food_description)
TextView food_description;
@BindView(R.id.food_price)
TextView food_price;
@BindView(R.id.number_button)
ElegantNumberButton numberButton;
@BindView(R.id.ratingBar)
RatingBar ratingBar;
@BindView(R.id.btnShowComment)
Button btnShowComment;
@BindView(R.id.rdi_group_size)
RadioGroup rdi_group_size;
@BindView(R.id.img_add_addon)
ImageView img_add_on;
@BindView(R.id.chip_group_user_selected_addon)
ChipGroup chip_group_user_selected_addon;

@OnClick(R.id.img_add_addon)
void onAddonClick()
{
    if(Common.selectedFood.getAddon() != null)
    {
        displayAddonList(); //show all addon options
        addonBottomSheetDialog.show();
    }
}

private void displayAddonList() {
    if(Common.selectedFood.getAddon().size() > 0)
    {
        chip_group_addon.clearCheck(); //Clear check all
        chip_group_addon.removeAllViews();

        edt_search.addTextChangedListener(this);

        //Add all view
        for(AddonModel addonModel:Common.selectedFood.getAddon())
        {

                Chip chip = (Chip)getLayoutInflater().inflate(R.layout.layout_addon_item,null);
                chip.setText(new StringBuilder(addonModel.getName()).append("(+$")
                        .append(addonModel.getPrice()).append(")"));
                chip.setOnCheckedChangeListener((compoundButton, b) -> {
                    if(b)
                    {
                        if (Common.selectedFood.getUserSelectedAddon() == null)
                            Common.selectedFood.setUserSelectedAddon(new ArrayList<>());
                        Common.selectedFood.getUserSelectedAddon().add(addonModel);
                    }
                });
                chip_group_addon.addView(chip);

        }

    }
}

@OnClick(R.id.btn_rating)
void onRatingButtonClick()
{
    showDialogRating();
}

@OnClick(R.id.btnShowComment)
void onShowCommentButtonClick() {
    CommentFragment commentFragment = CommentFragment.getInstance();
    commentFragment.show(getActivity().getSupportFragmentManager(),"CommentFragment");
}

private void showDialogRating() {
    androidx.appcompat.app.AlertDialog.Builder builder = new androidx.appcompat.app.AlertDialog.Builder(getContext());
    builder.setTitle("Rating Food");
    builder.setMessage("Please fill information");

    View itemView = LayoutInflater.from(getContext()).inflate(R.layout.layout_rating,null);

    RatingBar ratingBar = (RatingBar)itemView.findViewById(R.id.rating_bar);
    EditText edt_comment = (EditText)itemView.findViewById(R.id.edt_comment);

    builder.setView(itemView);

    builder.setNegativeButton("CANCEL", (dialogInterface, i) -> {
        dialogInterface.dismiss();
    });
    builder.setPositiveButton("OK", (dialogInterface, i) -> {
        CommentModel commentModel = new CommentModel();
        commentModel.setName(Common.currentUser.getName());
        commentModel.setUsername(Common.currentUser.getUsername());
        commentModel.setComment(edt_comment.getText().toString());
        commentModel.setRatingValue(ratingBar.getRating());
        Map<String,Object> serverTimeStamp = new HashMap<>();
        serverTimeStamp.put("timeStamp", ServerValue.TIMESTAMP);
        commentModel.setCommentTimeStamp(serverTimeStamp);

        foodDetailViewModel.setCommentModel(commentModel);

    });

    AlertDialog dialog = builder.create();
    dialog.show();
}


public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    foodDetailViewModel =
            new ViewModelProvider(this).get(FoodDetailViewModel.class);
    View root = inflater.inflate(R.layout.fragment_food_detail, container, false);
    unbinder = ButterKnife.bind(this,root);
    initViews();
    foodDetailViewModel.getMutableLiveDataFood().observe(getViewLifecycleOwner(), foodModel -> {
        displayInfo(foodModel);
    });
    foodDetailViewModel.getMutableLiveDataComment().observe(getViewLifecycleOwner(),commentModel -> {
        submitRatingToFirebase(commentModel);
    });
    return root;
}

private void initViews() {
    waitingDialog = new SpotsDialog.Builder().setCancelable(false).setContext(getContext()).build();

    addonBottomSheetDialog = new BottomSheetDialog(getContext(),R.style.DialogStyle);
    View layout_addon_display = getLayoutInflater().inflate(R.layout.layout_addon_display,null);
    chip_group_addon = (ChipGroup)layout_addon_display.findViewById(R.id.chip_group_addon);
    edt_search = (EditText)layout_addon_display.findViewById(R.id.edt_search);
    addonBottomSheetDialog.setContentView(layout_addon_display);

    addonBottomSheetDialog.setOnDismissListener(dialogInterface -> {
        displayUserSelectedAddon();
        calculateTotalPrice();
    });
}

private void displayUserSelectedAddon() {
    if(Common.selectedFood.getUserSelectedAddon() !=null &&
    Common.selectedFood.getUserSelectedAddon().size() > 0)
    {
        chip_group_user_selected_addon.removeAllViews(); //clear all view
        for(AddonModel addonModel : Common.selectedFood.getUserSelectedAddon()) //Add all available addon to list
        {
            Chip chip = (Chip)getLayoutInflater().inflate(R.layout.layout_chip_with_delete_icon, null);
            chip.setText(new StringBuilder(addonModel.getName()).append("(+$")
            .append(addonModel.getPrice()).append(")"));
            chip.setClickable(false);
            chip.setOnCloseIconClickListener(view -> {
                //Remove when user select delete
                chip_group_user_selected_addon.removeView(view);
                Common.selectedFood.getUserSelectedAddon().remove(addonModel);
                calculateTotalPrice();
            });
            chip_group_user_selected_addon.addView(chip);
        }
    }else if(Common.selectedFood.getUserSelectedAddon().size() == 0)
        chip_group_user_selected_addon.removeAllViews();
}

private void submitRatingToFirebase(CommentModel commentModel) {
    waitingDialog.show();
    //Submit comment to Ref
    FirebaseDatabase.getInstance()
            .getReference(Common.COMMENT_REF)
            .child(Common.selectedFood.getId())
            .push()
            .setValue(commentModel)
            .addOnCompleteListener(task -> {
                if(task.isSuccessful())
                {
                    //After submit to CommentRef, update value in food
                    addRatingToFood(commentModel.getRatingValue());
                }
            });
}

private void addRatingToFood(float ratingValue) {
    FirebaseDatabase.getInstance()
            .getReference(Common.CATEGORY_REF)
            .child(Common.categorySelected.getMenu_id()) //select category
    .child("foods") // select array list 'foods' of this category
    .child(Common.selectedFood.getKey()) //food item is array list
    .addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists())
            {
                FoodModel foodModel = dataSnapshot.getValue(FoodModel.class);
                foodModel.setKey(Common.selectedFood.getKey());

                //Apply rating
                if(foodModel.getRatingValue() == null)
                    foodModel.setRatingValue(0d);
                if(foodModel.getRatingCount() == null)
                    foodModel.setRatingCount(0l);
                double sumRating = (foodModel.getRatingValue() * foodModel.getRatingCount())+ratingValue;
                long ratingCount = foodModel.getRatingCount()+1;
                double result = sumRating/ratingCount;

                Map<String,Object> updateData = new HashMap<>();
                updateData.put("ratingValue",result);
                updateData.put("ratingCount",ratingCount);

                //Update data variable
                foodModel.setRatingValue(result);
                foodModel.setRatingCount(ratingCount);

                dataSnapshot.getRef()
                        .updateChildren(updateData)
                        .addOnCompleteListener(task -> {
                            waitingDialog.dismiss();
                            if(task.isSuccessful())
                            {
                                Toast.makeText(getContext(), "Thank you", Toast.LENGTH_SHORT).show();
                                Common.selectedFood = foodModel;
                                foodDetailViewModel.setFoodModel(foodModel); //Call refresh
                            }
                        });

            }
            else
                waitingDialog.dismiss();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            waitingDialog.dismiss();
            Toast.makeText(getContext(), ""+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

private void displayInfo(FoodModel foodModel) {
    Glide.with(getContext()).load(foodModel.getImage()).into(img_food);
    food_name.setText(new StringBuilder(foodModel.getName()));
    food_description.setText(new StringBuilder(foodModel.getDescription()));
    food_price.setText(new StringBuilder(foodModel.getPrice().toString()));

    if(foodModel.getRatingValue() != null)
        ratingBar.setRating(foodModel.getRatingValue().floatValue());

    ((AppCompatActivity)getActivity())
            .getSupportActionBar()
            .setTitle(Common.selectedFood.getName());

    //Size
    for(SizeModel sizeModel: Common.selectedFood.getSize())
    {
        RadioButton radioButton = new RadioButton(getContext());
        radioButton.setOnCheckedChangeListener((compoundButton, b) -> {
            if(b)
                Common.selectedFood.setUserSelectedSize(sizeModel);
            calculateTotalPrice(); //Update price
        });

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,
                LinearLayout.LayoutParams.MATCH_PARENT,
                1.0f);
        radioButton.setLayoutParams(params);
        radioButton.setText(sizeModel.getName());
        radioButton.setTag(sizeModel.getPrice());

        rdi_group_size.addView(radioButton);

    }

    if(rdi_group_size.getChildCount() > 0)
    {
        RadioButton radioButton = (RadioButton)rdi_group_size.getChildAt(0);
        radioButton.setChecked(true); //Default first select
    }

    calculateTotalPrice();
}

private void calculateTotalPrice() {
    double totalPrice = Double.parseDouble(Common.selectedFood.getPrice().toString()),displayPrice=0.0;

    //Addon
    if(Common.selectedFood.getUserSelectedAddon() != null && Common.selectedFood.getUserSelectedAddon().size() > 0)
        for(AddonModel addonModel : Common.selectedFood.getUserSelectedAddon())
            totalPrice+=Double.parseDouble(addonModel.getPrice().toString());

    //size
    totalPrice += Double.parseDouble(Common.selectedFood.getUserSelectedSize().getPrice().toString());

    displayPrice = totalPrice * (Integer.parseInt(numberButton.getNumber()));
    displayPrice = Math.round(displayPrice*100.0/100.0);

    food_price.setText(new StringBuilder("").append(Common.formatPrice(displayPrice)).toString());
}

@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    //Null
}

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    chip_group_addon.clearCheck();
    chip_group_addon.removeAllViews();

    for(AddonModel addonModel:Common.selectedFood.getAddon())
    {
        if(addonModel.getName().toLowerCase().contains(charSequence.toString().toLowerCase()))
        {
            Chip chip = (Chip)getLayoutInflater().inflate(R.layout.layout_addon_item,null);
            chip.setText(new StringBuilder(addonModel.getName()).append("(+$")
            .append(addonModel.getPrice()).append(")"));
            chip.setOnCheckedChangeListener((compoundButton, b) -> {
                if(b)
                {
                    if (Common.selectedFood.getUserSelectedAddon() == null)
                        Common.selectedFood.setUserSelectedAddon(new ArrayList<>());
                    Common.selectedFood.getUserSelectedAddon().add(addonModel);
                }
            });
            chip_group_addon.addView(chip);
        }
    }
}

@Override
public void afterTextChanged(Editable editable) {

}

SizeModel.java

public class SizeModel {
private String name;
private Long price;

public SizeModel() {
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Long getPrice() {
    return price;
}

public void setPrice(Long price) {
    this.price = price;
}
Lee Zi Jie
  • 23
  • 5
  • Checkout this line of code - `totalPrice += Double.parseDouble(Common.selectedFood.getUserSelectedSize().getPrice().toString());` – Amit Dash Jun 15 '21 at 15:46
  • checked but unsure what was going on :( – Lee Zi Jie Jun 15 '21 at 15:54
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Amit Dash Jun 15 '21 at 17:41
  • In addition to viewing Amit's link to better understand what a null pointer is, review the logcat details (on the tab at the bottom of Android Studio) when your code errors out with the NPE. It usually references the exact line number in the file that is causing the issue. – shagberg Jun 15 '21 at 19:08

0 Answers0