Search code examples
javaandroidandroid-dialogfragmentratingbar

Android app crashes after RatingBar DialogFragment closes


The purpose of my app is to retrieve a value out of 5 from a rating bar through a custom dialog and display it in a TextView in the main activity. When I tap the button I've outlined in red in the image below, the app crashes and shuts down.

The app consists of 2 classes/activities. The main activity and the custom dialog activity.

The code for both files can be found below:

enter image description here

enter image description here

MainActivity.java:

package com.example.mealrater;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements MealRaterDialog.SaveRating {

    public EditText restaurant, dish;
    public TextView ratingDisplay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        restaurant = findViewById(R.id.etRestaurant);
        dish = findViewById(R.id.etDish);

        RateMealButton();

    }

    @Override
    public void finishMealRaterDialog(String rating) {
        ratingDisplay = findViewById(R.id.tvRatingDisplay);
        ratingDisplay.setText(rating);
    }

    private void RateMealButton() {

        Button rate = findViewById(R.id.btnRate);
        rate.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                FragmentManager fm = getSupportFragmentManager();
                MealRaterDialog mealRaterDialog = new MealRaterDialog();
                mealRaterDialog.show(fm, "RateMeal");

            }
        });
    }
}

MealRaterDialog.java:

package com.example.mealrater;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RatingBar;
import androidx.fragment.app.DialogFragment;

public class MealRaterDialog extends DialogFragment {

    String rating;

    public interface SaveRating {
        void finishMealRaterDialog(String rating);
    }

    public MealRaterDialog() {
    }

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

        final View view = inflater.inflate(R.layout.meal_rater, container);
        getDialog().setTitle("Rate your meal");

        Button save = view.findViewById(R.id.btnSaveRating);
        save.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                RatingBar ratingBar = view.findViewById(R.id.rbMeal);
                rating = String.valueOf(ratingBar.getRating());
                SaveItem(String.valueOf(rating));

            }
        });
        return view;
    }

    private void SaveItem(String rating) {

        MealRaterDialog.SaveRating activity = (MealRaterDialog.SaveRating) getActivity();
        activity.finishMealRaterDialog(rating);
        getDialog().dismiss();

    }
}

I'm new to Android Studio and would also like to receive tips on how to improve this question. Thank you.

Logcat error:

2021-04-28 16:04:35.240 18144-18144/com.example.mealrater E/libc: Access denied finding property "ro.serialno"
2021-04-28 16:04:42.709 18144-18144/com.example.mealrater E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mealrater, PID: 18144
    java.lang.NullPointerException: Attempt to invoke virtual method 'float android.widget.RatingBar.getRating()' on a null object reference
        at com.example.mealrater.MealRaterDialog$1.onClick(MealRaterDialog.java:35)
        at android.view.View.performClick(View.java:7448)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View.performClickInternal(View.java:7425)
        at android.view.View.access$3600(View.java:810)
        at android.view.View$PerformClick.run(View.java:28305)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)


Solution

  • There are severall fixes for this.

    First of all, You should define the ratingBar widget before the onClick. Right now it is creating the variable each time you click on the button. Define it after Button save = view.findViewById(R.id.btnSaveRating); line.

    Second of all, As you are using a Dialog fragment, all the logic of the click should be called on the override funtion called onViewCreated(). Not in the OnCreateView() as you are doing right now. Let me know if it works for you.