A bug in Android or problem with Spinner in full screen mode


Yesterday, my friend Max wrote me in GTalk about one unusual problem. He develops a kind of full-screen application that calls a dialogue with the widget Spinner. And it would be cool, but there is a bug - when you click on the Spinner in full screen mode with the appearance of selection dialog Status Bar appears for 1-2 seconds. This situation occurs if the Spinner is a large number of items. It looks like this:


image

I began to explore the sources of the Spinner and discovered that when displaying the dialog with the elements when you click on - Spinner creates a dialogue that does not include the full screen versionThe code looks as follows.
    @Override
    public boolean performClick() {
        boolean handled = super.performClick();
        if (!handled) {
            handled = true;
            Context context = getContext();
            final DropDownAdapter adapter = new DropDownAdapter(getAdapter());
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            if (mPrompt != null) {
                builder.setTitle(mPrompt);
            }
            mPopup = builder.setSingleChoiceItems(adapter,
                    getSelectedItemPosition(), this).show();
        }
        return handled;
    }

There was only one solution in my head - create a class based on the Spinner and cut off his metod performClick (). But the difficulty lies in the fact that the reference to dialogue Spinner is stored in the private variable mPopup. This problem, we went around, using reflection to access this variable after you create the dialog and call the method necessary to set the properties dialog to properly display it full screenTo increase the security of this method for the solution to our problem, we abstracted from the field name and mPopup just the cycle of looking for a variable of type AlertDialog, so even if the developers change the name of the variable, the code will work. Here is the code of the new class:


package maximyudin.spinnerbug;
import java.lang.reflect.Field;import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.WindowManager;
import android.widget.Spinner;

public class NoTitleSpinner extends Spinner {
    public NoTitleSpinner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public NoTitleSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoTitleSpinner(Context context) {
        super(context);
    }

    @Override
    public boolean performClick() {
        boolean status = super.performClick();
        Field privateStringField = null;
        try {
            Field[] fields = Spinner.class.getDeclaredFields();
            for (Field field : fields) {
                if (field.getType().getName()
                        .equals(AlertDialog.class.getName())) {
                    privateStringField = field;
                    break;
                }
            }
            if (privateStringField == null) {
                return false;
            }

            privateStringField.setAccessible(true);
            AlertDialog dialog = (AlertDialog) privateStringField.get(this);
            dialog.getWindow().setFlags(
                    WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
        return status;
    }
}

Now instead of Spinner you need to use our NoTitleSpinner in the code and xml.
Fully project code posted here.

P.S. We've added this bug to the bug-report - follow the news here
 — code.google.com/p/android/issues/detail?id=11419