Question

What I'm trying to archive: I want a dialog with a custom view in it, but I want the standard icon, title, buttons from the AlertDialog.

What I'm doing is this custom dialog class:

public class CustomDialog extends AlertDialog.Builder {

    private Activity activity;
    private View root;

    public CustomDialog(Activity context) {
        super(context);
        this.activity = context;
    }

    public void setView(int layoutResID) {
        LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        root = inflater.inflate(layoutResID, (ViewGroup) activity.findViewById(R.id.dialog_root), false);
        ScrollView scroller = new ScrollView(activity);
        scroller.addView(root);
        setView(scroller);
    }

    public void setCustomView(View v) {
        ScrollView scroller = new ScrollView(activity);
        scroller.addView(v);
        setView(scroller);
    }

    public View getRoot() {
        return root;
    }

    @Override
    public AlertDialog create() {
        AlertDialog dialog = super.create();

        dialog.getWindow().getAttributes().width = LayoutParams.MATCH_PARENT;

        return dialog;
    }
}

This works pretty good, expect the TextView colors aren't correct on pre-Honeycomb and Honeycomb devices. I'm using the Holo.Light theme so the standard text color is black, but the background color of dialogs on pre-Honeycomb devices too. And on Honeycomb devices the dialog background is white. So what I did is, I added a dialogTextColor=white in the styles.xml in the values folder and dialogTextColor=black in the values-v11 folder. Then I had to add the style attribute to every TextView that I'm using in a custom dialog. This worked out until ICS and it's clear why -> v11. I could change it, but I want to have a custom dialog which does everything correct: The text color on pre-Honeycomb, Honeycomb, ICS (and whatever will come in the future) based on the application theme, the width of the dialog, the standard buttons, title, icon from the AlertDialog.

Was it helpful?

Solution

The trick here is that a Context is associated with a theme. That theme determines all sorts of things like default text colors, etc.

Before Honeycomb Dialogs always had the same theme whether they were generated from light or dark themed Activities, and with the exception of lists Dialogs were dark background, light foreground. In Honeycomb and forward, Dialogs have different themes determined by the Activity that spawns them.

When inflating content in a Dialog, always use the Context returned by the Dialog#getContext() method instead of the Activity that spawned the Dialog. Instead of the line of code you use to get your LayoutInflater above, try:

LayoutInflater inflater = LayoutInflater.from(getContext());

Edit: It looks like you're using an AlertDialog.Builder instead of a Dialog. AlertDialog.Builder added a getContext() method for this purpose in API 11 (Android 3.0, a.k.a. Honeycomb) but it didn't exist before that. You can build your own themed context with a ContextThemeWrapper for older devices. Just make sure you never try to call that method on an older version of the platform. You can guard it with a simple check:

Context themedContext;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    themedContext = getContext();
} else {
    themedContext = new ContextThemeWrapper(activity, android.R.style.Theme_Dialog);
}
LayoutInflater inflater = LayoutInflater.from(themedContext);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top