Search code examples
androidandroid-layoutandroid-themeandroid-inflateandroid-version

Inflated AlertDialogs unreadable on Android 4.X while looking perfect on Android 2.X


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()?


Solution

  • 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.