Emzor
Emzor

Reputation: 1368

How to Perform an Action Based on User's Selection on Dialog Fragment List

I'm trying to perform an action (in this case display a smiley in ImageView for each mood selected) based on user's selection from a Dialogfragment list. My code builds and runs successfully, but when I click Ok button, my app crashes: "Unfortunately, Dialog List has stopped."

Here's my DialogFragment class

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.widget.ImageView;
import android.widget.Toast;


public class SingleChoiceClass extends DialogFragment {

final CharSequence[] items = {"Ecstatic", "Happy", "Indifferent", "Upset"};
String selection;
private int item;
public ImageView imageView;


@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    builder.setTitle("Select Your Mood");
    builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface arg0, int arg1) {
            switch (arg1) {
                case 0:
                    selection = (String) items[arg1];
                    break;
                case 1:
                    selection = (String) items[arg1];
                    break;
                case 2:
                    selection = (String) items[arg1];
                    break;
                case 3:
                    selection = (String) items[arg1];
                    break;

            }

        }   // TODO: 11/4/15 WHY IS APP CRASHING WHEN I setImageResource
    });
    builder.setPositiveButton("Send", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {

            if (items[item].equals("Ecstatic")) {
                // Do stuff
                imageView.setImageResource(R.drawable.green_smiley);
                Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();

            } else if (items[item].equals("Happy")) {
                // Do stuff
                imageView.setImageResource(R.drawable.yellow_smiley);
                Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();

            } else if (items[item].equals("Indifferent")) {
                // Do stuff
                imageView.setImageResource(R.drawable.orange_smiley);
                Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();

            } else if (items[item].equals("Upset")) {
                // Do stuff
                imageView.setImageResource(R.drawable.red_smiley);
                Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();
            }
        }
    });
    return builder.create();
    }
}

And here's my MainActivity class

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.ImageView;


public class MainActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    SingleChoiceClass my_dialog = new SingleChoiceClass();
    my_dialog.show(getSupportFragmentManager(), "my_dialog");
    my_dialog.setCancelable(false);


    ImageView imageView = (ImageView) findViewById(R.id.image);

    }

}

Finally, how can I get user's selection without using the OK button as is the default practice in most android inbuilt apps? See image below:

enter image description here

Upvotes: 1

Views: 619

Answers (2)

Emzor
Emzor

Reputation: 1368

I was finally able to solve my challenge like this:

I retained Daniel Nugent's suggestion for MainActivity. But I changed my DialogFragment class like this:

public class SingleChoiceClass extends DialogFragment {

final CharSequence[] items = {"Ecstatic", "Happy", "Indifferent", "Upset"};
String selection;
private int item;


@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    final MainActivity activity = (MainActivity) getActivity();

    final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    builder.setTitle("Select Your Mood");
    builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface arg0, int arg1) {
            switch (arg1) {
                case 0:
                    selection = (String) items[arg1];
                    // Do your magic
                    activity.setImage(R.drawable.green_smiley);
                    dismiss();
                    break;

                case 1:
                    selection = (String) items[arg1];
                    // Do your magic
                    activity.setImage(R.drawable.yellow_smiley);
                    dismiss();
                    break;

                case 2:
                    selection = (String) items[arg1];
                    // Do your magic
                    activity.setImage(R.drawable.orange_smiley);
                    dismiss();
                    break;

                case 3:
                    selection = (String) items[arg1];
                    // Do your magic
                    activity.setImage(R.drawable.red_smiley);
                    dismiss();
                    break;
            }
        }
    });
    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {      
        public void onClick(DialogInterface dialog, int which) {
            //Exit app
            activity.finish(); 
            // Or try to relaunch dialog
       }
    });
    return builder.create();
  }

}

Upvotes: 0

Daniel Nugent
Daniel Nugent

Reputation: 43322

You have an orphaned imageView in your DialogFragment, that is probably causing a NullPointerException. First and foremost, remove all imageView references in the DialogFragment.

In order to fix your main issue, first create a method in MainActivity that is called by the DialogFragment when OK is clicked:

public void setImage(int imageID) {
    imageView.setImageResource(imageID);
}

Then, add the code to call that method from the DialogFragment:

builder.setPositiveButton("Send", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        //Added:
        MainActivity activity = (MainActivity) getActivity();

        if (items[item].equals("Ecstatic")) {
            // Do stuff
            //imageView.setImageResource(R.drawable.green_smiley); //removed
            //Added:
            if (activity != null) {
                  activity.setImage(R.drawable.green_smiley);
            }

            Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();

        } else if (items[item].equals("Happy")) {
            // Do stuff
            //imageView.setImageResource(R.drawable.yellow_smiley);
            //Added:
            if (activity != null) {
                  activity.setImage(R.drawable.R.drawable.yellow_smiley);
            }
            Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();

        } else if (items[item].equals("Indifferent")) {
            // Do stuff
            imageView.setImageResource(R.drawable.orange_smiley);
            Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();

        } else if (items[item].equals("Upset")) {
            // Do stuff
            //imageView.setImageResource(R.drawable.red_smiley);
            //Added:
            if (activity != null) {
                  activity.setImage(R.drawable.red_smiley);
            }
            Toast.makeText(getActivity(), "" + selection, Toast.LENGTH_SHORT).show();
        }
    }
});
return builder.create();
}

You will also need to make imageView a member variable of MainActivity:

public class MainActivity extends FragmentActivity {

//Added:
ImageView imageView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    SingleChoiceClass my_dialog = new SingleChoiceClass();
    my_dialog.show(getSupportFragmentManager(), "my_dialog");
    my_dialog.setCancelable(false);

    //modified:
    imageView = (ImageView) findViewById(R.id.image);

    }

    public void setImage(int imageID) {
        imageView.setImageResource(imageID);
    }

}

Note that you might want to use interface callbacks instead of calling the method directly on the Activity, see here for details.

Upvotes: 2

Related Questions