javaandroidlistviewandroid-alertdialogandroid-listfragment

How to show alert dialog for certain list item


I'm trying to show an alert dialog whenever I select a particular list item whereas the others would open a new fragment. However after inserting the alreat dialog code, an error is then returned. I don't understand why I'm getting this error when 'intent' has already been initialised. What can be done to resolve this problem?

Variable 'intent' might not have been initialized

FragmentFruitChooser

public class FragmentFruitChooser extends ListFragment {

    public FragmentFruitChooser() {
        // Required empty constructor
    }

    /**
     * Whether or not the activity is in two-pane mode, i.e. running on a tablet
     * device.
     */
    public boolean mTwoPane;

    public static FragmentFruitChooser newInstance() {
        return new FragmentFruitChooser();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_fruit_chooser, container, false);
        initialize();
        return view;
    }

    List<Fruits> list = new ArrayList<>();
    private void initialize() {
        String[] items = getActivity().getResources().getStringArray(R.array.fruit_names);
        String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.fruit_descriptions);
        for (int n = 0; n < items.length; n++){
            Fruit fruit = new Fruit();
            fruit.setID();
            fruit.setName(items[n]);
            fruit.setDescription(itemDescriptions[n]);
            list.add(fruit);
        }

        FruitListAdapter mAdapter = new FruitListAdapter(list, getActivity());
        setListAdapter(mAdapter);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        View v = getView();

        mTwoPane = getActivity().findViewById(R.id.detail_container) != null;

        assert v != null;
        ListView lv = (ListView)v.findViewById(android.R.id.list);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // get the adapter, then get the name from the adapter at that position
                FruitListAdapter adapter = (FruitListAdapter) parent.getAdapter();

                //reverse the selected state in data model
                for (int i = 0; i < adapter.getCount(); i++) {
                    Fruit fruit = (Fruit)adapter.getItem(i);
                    fruit.setSelected(i == position);
                }
                Fruit fruit = (Fruit)adapter.getItem(position);

                if (!mTwoPane) {

                    Intent intent;
                    if (fruit.getFruit().equals(view.getResources().getString(R.string.apple))) {
                        intent = new Intent(getActivity(), FruitAppleActivity.class);
                    } else if (fruit.getFruit().equals(view.getResources().getString(R.string.orange))) {
                        intent = new Intent(getActivity(), FruitOrangeActivity.class);
                    } else if (fruit.getFruit().equals(view.getResources().getString(R.string.tomato))) {
 AlertDialog ad = new AlertDialog.Builder(getContext())
            .create();
    ad.setCancelable(false);
    ad.setTitle("Seeded Fruit");
    ad.setMessage("This fruit contains seeds.");
    ad.setButton(context.getString(R.string.ok_text), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });
ad.show();
                    } else {
                        intent = new Intent(getActivity(), FruitAppleActivity.class);
                    }
                    startActivity(intent);
                }
            }

        });

        super.onActivityCreated(savedInstanceState);
    }
}

Solution

  • Not quite sure how your program works, but in your second else if statement, your intent is not initialized, yet startActivity(intent) is still called:

    } else if (fruit.getFruit().equals(view.getResources().getString(R.string.tomato))) {
                            AlertDialog ad = new AlertDialog.Builder(getContext())
                                    .create();
                            ad.setCancelable(false);
                            ad.setTitle("Seeded Fruit");
                            ad.setMessage("This fruit contains seeds.");
                            ad.setButton(context.getString(R.string.ok_text), new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            });
                            ad.show();
                        } else {
                            intent = new Intent(getActivity(), FruitAppleActivity.class);
                        }
    
                        startActivity(intent);
    

    You could do what @seanAshmore answered but it may still result to an NPE. I suggest simply adding a null checker for the intent before actually calling startActivity(), like so:

    if (intent != null) {
                            startActivity(intent);
                        } else {
                            Log.d(FragmentFruitChooser.class.getSimpleName(), "Intent is null");
                        }
    

    You could just put separate Intent intent = new Intent(...) for each if/elif/else statement just to be sure. But tis your code, so do as you will.