Brian Brian - 1 month ago 15
Android Question

Need help getting a custom layout to work with my Android AlertDialog

I have successfully created a working AlertDialog for my Android application:

public class MyClass extends DialogFragment{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
ArrayList selectedItems = new ArrayList();
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.pick_toppings)
builder.setMultiChoiceItems(R.array.my_array, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
selectedItems.add(which);
} else if (selectedItems.contains(which)) {
selectedItems.remove(Integer.valueOf(which));
}
}
});
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// do stuff here ...
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// do stuff here ...
}
});

return builder.create();
}
}


This MultiChoiceItems list is backed by an array in
/res/values/array.xml


<resources>
<array name="my_array">
<item>item 01</item>
<item>item 02</item>
<item>item 03</item>
<item>item 04</item>
<item>item 05</item>
</array>
</resources>


From my Activity, I call the AlertDialog this way:

MyClass myClass = new MyClass();
myClass.show(getSupportFragmentManager(), "My Dialog");


What I want to do now is use a custom layout with the AlertDialog so that I can do things like alternate-row shading, custom buttons, and add an EditText so I can have an "other" option with the ability to fill in the "other".

After doing some googling, it looks like I need to create a new layout, and set the view of the AlertDialog to this layout. So, I created a layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="other"
android:textSize="18sp"/>
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>


Then I added this to my DialogFragment class:

LayoutInflater layoutInflater = getActivity().getLayoutInflater();
View view = layoutInflater.inflate(R.layout.my_new_layout, null);


then

builder.setView(view);


As you can guess, this did not work. The new CheckBox and EditText was inserted after my other checkboxes that were populated from my array, but it looks terrible, and I don't appear to have any control over the appearance of the checkboxes created from the array.

Like I said, I would like the ability to add this new CheckBox/EditText combination, as well as have the ability to customize the look of the entire AlertDialog.

I really want to use the array from
/res/values/array.xml
so that I do not have to hard code a new option if I want to add new items to the list.

Is what I am wanting to do possible? If so, some advice would be great.

Thanks

This is what I would like my AlertDialog to look/act like:

Answer

Ok, I finally figured this out on my own. Here is my resolution:

New Layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="right">
</LinearLayout>

New Class:

public class MyClass extends DialogFragment{
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String[] theOptions = getResources().getStringArray(R.array.options);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(R.string.pick_toppings)

        LayoutInflater layoutInflater = getActivity().getLayoutInflater();
        LinearLayout view = (LinearLayout) layoutInflater.inflate(R.layout.my_layout, null);

        for(String option : theOptions){
            CheckBox checkbox = new CheckBox(getContext());
            checkbox.setText(option);
            view.addView(checkbox);
        }

        LinearLayout otherLinearLayout = new LinearLayout(getContext());
        otherLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
        otherLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        otherLinearLayout.setId(R.id.otherLinearLayout);

        CheckBox otherCheckBox = new CheckBox(getContext());
        otherCheckBox.setText("other");
        otherCheckBox.setId(R.id.otherCheckBox);

        EditText otherEditText = new EditText(getContext());
        otherEditText.setId(R.id.otherEditText);

        otherLinearLayout.addView(otherCheckBox);
        otherLinearLayout.addView(otherEditText);

        view.addView(otherLinearLayout);

        builder.setView(view);

        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                // do stuff here ...
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                // do stuff here ...
            }
        });

        return builder.create();
    }
}