2

In order to show dialogs with rich content and input elements, I use Android's AlertDialog.Builder to create an object of AlertDialog and then I use the system's LayoutInflater to set the content (setView(...)) to some XML layout file.

This looks perfect on Android 2.X (dark background, white text):

enter image description here

But on Android 4.X it is not readable at all:

enter image description here

Note: These dialogs are not the same, of course, but the problem occurs for both dialogs.

So what am I doing wrong? I'm using Theme.Light on API level < 11 and Theme.Holo.Light on >= 11.

Edit 1: And this is the code I use for inflating:

private LayoutInflater mGlobalInflater; // in Activity class
mGlobalInflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); // in Activity's onCreate()
mGlobalInflater.inflate(R.layout.input_dialog, null); // when needed

Edit 2: And here's the inflated XML for the "choose date" view:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:padding="15dp">
    <DatePicker
        android:id="@+id/input_date"
        android:startYear="1900"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        android:text="@string/hint" />
</LinearLayout>

Edit 3: As I found out now, the inflated dialog content is rendered correctly on Android <= 2.3.3 when using mGlobalInflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); and it is rendered correctly on Android >= 3.0 when using mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);. So the Context makes the difference. Why?

Edit 4:

The dialog is created and inflated inside of onContextItemSelected() of Activity:

AlertDialog.Builder dialogPoup = new AlertDialog.Builder(MainActivity.this);
dialogPoup.setTitle("abc123");
final View inputDialog = mGlobalInflater.inflate(R.layout.input_dialog, null);
// setting some properties of the view and its child views
dialogPoup.setView(inputDialog);

Is this correct? Or do I have to replace MainActivity.this by a variable mContext (for example) that the Activity's context was assigned to in onCreate()?

4

3 に答える 3

2

Instead of getting the LayoutInflater using getApplicationContext() like in your code above, use the one from your Activity instead like this:

    mGlobalInflater = LayoutInflater.from(this); // in Activity's onCreate()

This should hopefully use the matching theme for the dialog.

于 2012-10-05T20:05:35.007 に答える
1

When you say you're using Theme.Light and Theme.Holo.Light, it matters what you are applying this theme on.

It differs if its your Application or your Activity. If you're applying it on the Application level then if you get the Context from Application, you'd be inflating with that theme (similarly for Activity). You'd notice the difference if both themes are different for application vs activity.

Just keep that in mind when you're going through @Joe's answer above. You mentioned that @Joe's answer fixed the problem for api11+ but broke for those prior.

So just take a look at your AndroidManifest and see what you have for the themes for <application> and that particular <activity> that you're inflating the Dialog from.

Hope that helps

于 2012-10-11T19:43:44.407 に答える
1

The only working solution that I've found is the following:

    LayoutInflater mInflater, mGlobalInflater;
    mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= 11) {
        mGlobalInflater = mInflater;
    }
    else {
        mGlobalInflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
    }

Now you can use mInflater for normal inflating (such as: rows inside a ListView) and mGlobalInflater for inflating views inside of an AlertDialog (using setView()). This will then work across all API levels.

于 2012-10-12T16:15:36.453 に答える