FileDocCategorySizeDatePackage
AlertController.javaAPI DocAndroid 1.5 API34774Wed May 06 22:41:56 BST 2009com.android.internal.app

AlertController

public class AlertController extends Object

Fields Summary
private final android.content.Context
mContext
private final android.content.DialogInterface
mDialogInterface
private final android.view.Window
mWindow
private CharSequence
mTitle
private CharSequence
mMessage
private android.widget.ListView
mListView
private android.view.View
mView
private int
mViewSpacingLeft
private int
mViewSpacingTop
private int
mViewSpacingRight
private int
mViewSpacingBottom
private boolean
mViewSpacingSpecified
private android.widget.Button
mButtonPositive
private CharSequence
mButtonPositiveText
private android.os.Message
mButtonPositiveMessage
private android.widget.Button
mButtonNegative
private CharSequence
mButtonNegativeText
private android.os.Message
mButtonNegativeMessage
private android.widget.Button
mButtonNeutral
private CharSequence
mButtonNeutralText
private android.os.Message
mButtonNeutralMessage
private android.widget.ScrollView
mScrollView
private int
mIconId
private android.graphics.drawable.Drawable
mIcon
private android.widget.ImageView
mIconView
private android.widget.TextView
mTitleView
private android.widget.TextView
mMessageView
private android.view.View
mCustomTitleView
private boolean
mForceInverseBackground
private android.widget.ListAdapter
mAdapter
private int
mCheckedItem
private android.os.Handler
mHandler
View.OnClickListener
mButtonHandler
Constructors Summary
public AlertController(android.content.Context context, android.content.DialogInterface di, android.view.Window window)

        mContext = context;
        mDialogInterface = di;
        mWindow = window;
        mHandler = new ButtonHandler(di);
    
Methods Summary
static booleancanTextInput(android.view.View v)

        if (v.onCheckIsTextEditor()) {
            return true;
        }
        
        if (!(v instanceof ViewGroup)) {
            return false;
        }
        
        ViewGroup vg = (ViewGroup)v;
        int i = vg.getChildCount();
        while (i > 0) {
            i--;
            v = vg.getChildAt(i);
            if (canTextInput(v)) {
                return true;
            }
        }
        
        return false;
    
private voidcenterButton(android.widget.Button button)

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) button.getLayoutParams();
        params.gravity = Gravity.CENTER_HORIZONTAL;
        params.weight = 0.5f;
        button.setLayoutParams(params);
        View leftSpacer = mWindow.findViewById(R.id.leftSpacer);
        leftSpacer.setVisibility(View.VISIBLE);
        View rightSpacer = mWindow.findViewById(R.id.rightSpacer);
        rightSpacer.setVisibility(View.VISIBLE);
    
public android.widget.ButtongetButton(int whichButton)

        switch (whichButton) {
            case DialogInterface.BUTTON_POSITIVE:
                return mButtonPositiveMessage != null ? mButtonPositive : null;
            case DialogInterface.BUTTON_NEGATIVE:
                return mButtonNegativeMessage != null ? mButtonNegative : null;
            case DialogInterface.BUTTON_NEUTRAL:
                return mButtonNeutralMessage != null ? mButtonNeutral : null;
            default:
                return null;
        }
    
public android.widget.ListViewgetListView()

        return mListView;
    
public voidinstallContent()

        /* We use a custom title so never request a window title */
        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
        
        if (mView == null || !canTextInput(mView)) {
            mWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        }
        mWindow.setContentView(com.android.internal.R.layout.alert_dialog);
        setupView();
    
public booleanonKeyDown(int keyCode, android.view.KeyEvent event)

        if (mScrollView != null && mScrollView.executeKeyEvent(event)) return true;
        return false;
    
public booleanonKeyUp(int keyCode, android.view.KeyEvent event)

        if (mScrollView != null && mScrollView.executeKeyEvent(event)) return true;
        return false;
    
private voidsetBackground(android.widget.LinearLayout topPanel, android.widget.LinearLayout contentPanel, android.view.View customPanel, boolean hasButtons, android.content.res.TypedArray a, boolean hasTitle, android.view.View buttonPanel)

        
        /* Get all the different background required */
        int fullDark = a.getResourceId(
                R.styleable.AlertDialog_fullDark, R.drawable.popup_full_dark);
        int topDark = a.getResourceId(
                R.styleable.AlertDialog_topDark, R.drawable.popup_top_dark);
        int centerDark = a.getResourceId(
                R.styleable.AlertDialog_centerDark, R.drawable.popup_center_dark);
        int bottomDark = a.getResourceId(
                R.styleable.AlertDialog_bottomDark, R.drawable.popup_bottom_dark);
        int fullBright = a.getResourceId(
                R.styleable.AlertDialog_fullBright, R.drawable.popup_full_bright);
        int topBright = a.getResourceId(
                R.styleable.AlertDialog_topBright, R.drawable.popup_top_bright);
        int centerBright = a.getResourceId(
                R.styleable.AlertDialog_centerBright, R.drawable.popup_center_bright);
        int bottomBright = a.getResourceId(
                R.styleable.AlertDialog_bottomBright, R.drawable.popup_bottom_bright);
        int bottomMedium = a.getResourceId(
                R.styleable.AlertDialog_bottomMedium, R.drawable.popup_bottom_medium);
        int centerMedium = a.getResourceId(
                R.styleable.AlertDialog_centerMedium, R.drawable.popup_center_medium);
        
        /*
         * We now set the background of all of the sections of the alert.
         * First collect together each section that is being displayed along
         * with whether it is on a light or dark background, then run through
         * them setting their backgrounds.  This is complicated because we need
         * to correctly use the full, top, middle, and bottom graphics depending
         * on how many views they are and where they appear.
         */
        
        View[] views = new View[4];
        boolean[] light = new boolean[4];
        View lastView = null;
        boolean lastLight = false;
        
        int pos = 0;
        if (hasTitle) {
            views[pos] = topPanel;
            light[pos] = false;
            pos++;
        }
        
        /* The contentPanel displays either a custom text message or
         * a ListView. If it's text we should use the dark background
         * for ListView we should use the light background. If neither
         * are there the contentPanel will be hidden so set it as null.
         */
        views[pos] = (contentPanel.getVisibility() == View.GONE) 
                ? null : contentPanel;
        light[pos] = mListView == null ? false : true;
        pos++;
        if (customPanel != null) {
            views[pos] = customPanel;
            light[pos] = mForceInverseBackground;
            pos++;
        }
        if (hasButtons) {
            views[pos] = buttonPanel;
            light[pos] = true;
        }
        
        boolean setView = false;
        for (pos=0; pos<views.length; pos++) {
            View v = views[pos];
            if (v == null) {
                continue;
            }
            if (lastView != null) {
                if (!setView) {
                    lastView.setBackgroundResource(lastLight ? topBright : topDark);
                } else {
                    lastView.setBackgroundResource(lastLight ? centerBright : centerDark);
                }
                setView = true;
            }
            lastView = v;
            lastLight = light[pos];
        }
        
        if (lastView != null) {
            if (setView) {
                
                /* ListViews will use the Bright background but buttons use
                 * the Medium background.
                 */ 
                lastView.setBackgroundResource(
                        lastLight ? (hasButtons ? bottomMedium : bottomBright) : bottomDark);
            } else {
                lastView.setBackgroundResource(lastLight ? fullBright : fullDark);
            }
        }
        
        /* TODO: uncomment section below. The logic for this should be if 
         * it's a Contextual menu being displayed AND only a Cancel button 
         * is shown then do this.
         */
//        if (hasButtons && (mListView != null)) {
            
            /* Yet another *special* case. If there is a ListView with buttons
             * don't put the buttons on the bottom but instead put them in the
             * footer of the ListView this will allow more items to be
             * displayed.
             */
            
            /*
            contentPanel.setBackgroundResource(bottomBright);
            buttonPanel.setBackgroundResource(centerMedium);
            ViewGroup parent = (ViewGroup) mWindow.findViewById(R.id.parentPanel);
            parent.removeView(buttonPanel);
            AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                    AbsListView.LayoutParams.FILL_PARENT, 
                    AbsListView.LayoutParams.FILL_PARENT);
            buttonPanel.setLayoutParams(params);
            mListView.addFooterView(buttonPanel);
            */
//        }
        
        if ((mListView != null) && (mAdapter != null)) {
            mListView.setAdapter(mAdapter);
            if (mCheckedItem > -1) {
                mListView.setItemChecked(mCheckedItem, true);
                mListView.setSelection(mCheckedItem);
            }
        }
    
public voidsetButton(int whichButton, java.lang.CharSequence text, DialogInterface.OnClickListener listener, android.os.Message msg)
Sets a click listener or a message to be sent when the button is clicked. You only need to pass one of {@code listener} or {@code msg}.

param
whichButton Which button, can be one of {@link DialogInterface#BUTTON_POSITIVE}, {@link DialogInterface#BUTTON_NEGATIVE}, or {@link DialogInterface#BUTTON_NEUTRAL}
param
text The text to display in positive button.
param
listener The {@link DialogInterface.OnClickListener} to use.
param
msg The {@link Message} to be sent when clicked.


        if (msg == null && listener != null) {
            msg = mHandler.obtainMessage(whichButton, listener);
        }
        
        switch (whichButton) {

            case DialogInterface.BUTTON_POSITIVE:
                mButtonPositiveText = text;
                mButtonPositiveMessage = msg;
                break;
                
            case DialogInterface.BUTTON_NEGATIVE:
                mButtonNegativeText = text;
                mButtonNegativeMessage = msg;
                break;
                
            case DialogInterface.BUTTON_NEUTRAL:
                mButtonNeutralText = text;
                mButtonNeutralMessage = msg;
                break;
                
            default:
                throw new IllegalArgumentException("Button does not exist");
        }
    
public voidsetCustomTitle(android.view.View customTitleView)

see
AlertDialog.Builder#setCustomTitle(View)

        mCustomTitleView = customTitleView;
    
public voidsetIcon(int resId)
Set resId to 0 if you don't want an icon.

param
resId the resourceId of the drawable to use as the icon or 0 if you don't want an icon.

        mIconId = resId;
        if (mIconView != null) {
            if (resId > 0) {
                mIconView.setImageResource(mIconId);
            } else if (resId == 0) {
                mIconView.setVisibility(View.GONE);
            }
        }
    
public voidsetIcon(android.graphics.drawable.Drawable icon)

        mIcon = icon;
        if ((mIconView != null) && (mIcon != null)) {
            mIconView.setImageDrawable(icon);
        }
    
public voidsetInverseBackgroundForced(boolean forceInverseBackground)

        mForceInverseBackground = forceInverseBackground;
    
public voidsetMessage(java.lang.CharSequence message)

        mMessage = message;
        if (mMessageView != null) {
            mMessageView.setText(message);
        }
    
public voidsetTitle(java.lang.CharSequence title)

        mTitle = title;
        if (mTitleView != null) {
            mTitleView.setText(title);
        }
    
public voidsetView(android.view.View view)
Set the view to display in the dialog.

        mView = view;
        mViewSpacingSpecified = false;
    
public voidsetView(android.view.View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight, int viewSpacingBottom)
Set the view to display in the dialog along with the spacing around that view

        mView = view;
        mViewSpacingSpecified = true;
        mViewSpacingLeft = viewSpacingLeft;
        mViewSpacingTop = viewSpacingTop;
        mViewSpacingRight = viewSpacingRight;
        mViewSpacingBottom = viewSpacingBottom;
    
private booleansetupButtons()

        View defaultButton = null;
        int BIT_BUTTON_POSITIVE = 1;
        int BIT_BUTTON_NEGATIVE = 2;
        int BIT_BUTTON_NEUTRAL = 4;
        int whichButtons = 0;
        mButtonPositive = (Button) mWindow.findViewById(R.id.button1);
        mButtonPositive.setOnClickListener(mButtonHandler);

        if (TextUtils.isEmpty(mButtonPositiveText)) {
            mButtonPositive.setVisibility(View.GONE);
        } else {
            mButtonPositive.setText(mButtonPositiveText);
            mButtonPositive.setVisibility(View.VISIBLE);
            defaultButton = mButtonPositive;
            whichButtons = whichButtons | BIT_BUTTON_POSITIVE;
        }

        mButtonNegative = (Button) mWindow.findViewById(R.id.button2);
        mButtonNegative.setOnClickListener(mButtonHandler);

        if (TextUtils.isEmpty(mButtonNegativeText)) {
            mButtonNegative.setVisibility(View.GONE);
        } else {
            mButtonNegative.setText(mButtonNegativeText);
            mButtonNegative.setVisibility(View.VISIBLE);

            if (defaultButton == null) {
                defaultButton = mButtonNegative;
            }
            whichButtons = whichButtons | BIT_BUTTON_NEGATIVE;
        }

        mButtonNeutral = (Button) mWindow.findViewById(R.id.button3);
        mButtonNeutral.setOnClickListener(mButtonHandler);

        if (TextUtils.isEmpty(mButtonNeutralText)) {
            mButtonNeutral.setVisibility(View.GONE);
        } else {
            mButtonNeutral.setText(mButtonNeutralText);
            mButtonNeutral.setVisibility(View.VISIBLE);

            if (defaultButton == null) {
                defaultButton = mButtonNeutral;
            }
            whichButtons = whichButtons | BIT_BUTTON_NEUTRAL;
        }

        /*
         * If we only have 1 button it should be centered on the layout and
         * expand to fill 50% of the available space.
         */
        if (whichButtons == BIT_BUTTON_POSITIVE) {
            centerButton(mButtonPositive);
        } else if (whichButtons == BIT_BUTTON_NEGATIVE) {
            centerButton(mButtonNeutral);
        } else if (whichButtons == BIT_BUTTON_NEUTRAL) {
            centerButton(mButtonNeutral);
        }
        
        return whichButtons != 0;
    
private voidsetupContent(android.widget.LinearLayout contentPanel)

        mScrollView = (ScrollView) mWindow.findViewById(R.id.scrollView);
        mScrollView.setFocusable(false);
        
        // Special case for users that only want to display a String
        mMessageView = (TextView) mWindow.findViewById(R.id.message);
        if (mMessageView == null) {
            return;
        }
        
        if (mMessage != null) {
            mMessageView.setText(mMessage);
        } else {
            mMessageView.setVisibility(View.GONE);
            mScrollView.removeView(mMessageView);
            
            if (mListView != null) {
                contentPanel.removeView(mWindow.findViewById(R.id.scrollView));
                contentPanel.addView(mListView,
                        new LinearLayout.LayoutParams(FILL_PARENT, FILL_PARENT));
                contentPanel.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, 0, 1.0f));
            } else {
                contentPanel.setVisibility(View.GONE);
            }
        }
    
private booleansetupTitle(android.widget.LinearLayout topPanel)

        boolean hasTitle = true;
        
        if (mCustomTitleView != null) {
            // Add the custom title view directly to the topPanel layout
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            
            topPanel.addView(mCustomTitleView, lp);
            
            // Hide the title template
            View titleTemplate = mWindow.findViewById(R.id.title_template);
            titleTemplate.setVisibility(View.GONE);
        } else {
            final boolean hasTextTitle = !TextUtils.isEmpty(mTitle);
            
            mIconView = (ImageView) mWindow.findViewById(R.id.icon);
            if (hasTextTitle) {
                
                /* Display the title if a title is supplied, else hide it */
                mTitleView = (TextView) mWindow.findViewById(R.id.alertTitle);

                mTitleView.setText(mTitle);
                mIconView.setImageResource(R.drawable.ic_dialog_menu_generic);
                
                /* Do this last so that if the user has supplied any
                 * icons we use them instead of the default ones. If the
                 * user has specified 0 then make it disappear.
                 */
                if (mIconId > 0) {
                    mIconView.setImageResource(mIconId);
                } else if (mIcon != null) {
                    mIconView.setImageDrawable(mIcon);
                } else if (mIconId == 0) {
                    
                    /* Apply the padding from the icon to ensure the
                     * title is aligned correctly.
                     */
                    mTitleView.setPadding(mIconView.getPaddingLeft(),
                            mIconView.getPaddingTop(),
                            mIconView.getPaddingRight(),
                            mIconView.getPaddingBottom());
                    mIconView.setVisibility(View.GONE);
                }
            } else {
                
                // Hide the title template
                View titleTemplate = mWindow.findViewById(R.id.title_template);
                titleTemplate.setVisibility(View.GONE);
                mIconView.setVisibility(View.GONE);
                hasTitle = false;
            }
        }
        return hasTitle;
    
private voidsetupView()

        LinearLayout contentPanel = (LinearLayout) mWindow.findViewById(R.id.contentPanel);
        setupContent(contentPanel);
        boolean hasButtons = setupButtons();
        
        LinearLayout topPanel = (LinearLayout) mWindow.findViewById(R.id.topPanel);
        TypedArray a = mContext.obtainStyledAttributes(
                null, com.android.internal.R.styleable.AlertDialog, com.android.internal.R.attr.alertDialogStyle, 0);
        boolean hasTitle = setupTitle(topPanel);
            
        View buttonPanel = mWindow.findViewById(R.id.buttonPanel);
        if (!hasButtons) {
            buttonPanel.setVisibility(View.GONE);
        }

        FrameLayout customPanel = null;
        if (mView != null) {
            customPanel = (FrameLayout) mWindow.findViewById(R.id.customPanel);
            FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.custom);
            custom.addView(mView, new LayoutParams(FILL_PARENT, FILL_PARENT));
            if (mViewSpacingSpecified) {
                custom.setPadding(mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
                        mViewSpacingBottom);
            }
            if (mListView != null) {
                ((LinearLayout.LayoutParams) customPanel.getLayoutParams()).weight = 0;
            }
        } else {
            mWindow.findViewById(R.id.customPanel).setVisibility(View.GONE);
        }
        
        /* Only display the divider if we have a title and a 
         * custom view or a message.
         */
        if (hasTitle && ((mMessage != null) || (mView != null))) {
            View divider = mWindow.findViewById(R.id.titleDivider);
            divider.setVisibility(View.VISIBLE);
        }
        
        setBackground(topPanel, contentPanel, customPanel, hasButtons, a, hasTitle, buttonPanel);
        a.recycle();