Android Spinner、PopupWindow和Dialog的关系

来源:互联网 发布:单片机驱动发光二极管 编辑:程序博客网 时间:2024/06/05 11:36

最近再做一个从底部按钮点击弹出一列表框的效果,分别使用了SpinnerPopupWindowDialog,本文不涉及三者的具体使用方法,这是来解答我对这三个相似的控件的疑惑。
下面总结一下他们的区别:
Dialog在show()或者dismiss()时会有一个异步的回调,而PopupWindow则没有,这并不是说PopupWindow显示是阻塞的,而Dialog的显示是非阻塞的,因为Dialog的异步回调都是在Dialog显示完之后才进行的,所以PopupWindowDialog的显示方式是一样的,阻塞和非阻塞是针对Dialog的回调来说的
Dialog show()方法源码:

 public void show() {   ···省略···    try {               mWindowManager.addView(mDecor, l);               mShowing = true;               sendShowMessage();        } finally {        } }

sendShowMeassage():

private void sendShowMessage() {        if (mShowMessage != null) {            // Obtain a new message so this dialog can be re-used            Message.obtain(mShowMessage).sendToTarget();        }    }

mShowMessage会被mListenersHandler接收,mListenersHandler源码如下:

 private static final class ListenersHandler extends Handler {        private WeakReference<DialogInterface> mDialog;        public ListenersHandler(Dialog dialog) {            mDialog = new WeakReference<DialogInterface>(dialog);        }        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case DISMISS:                    ((OnDismissListener) msg.obj).onDismiss(mDialog.get());                    break;                case CANCEL:                    ((OnCancelListener) msg.obj).onCancel(mDialog.get());                    break;                case SHOW:                    ((OnShowListener) msg.obj).onShow(mDialog.get());                    break;            }        }    }

在Dialog显示完之后会执行((OnShowListener) msg.obj).onShow(mDialog.get());OnShowListener在这下面这段代码中进行设置。

 public void setOnShowListener(OnShowListener listener) {        if (listener != null) {            mShowMessage = mListenersHandler.obtainMessage(SHOW, listener);        } else {            mShowMessage = null;        }    }

Dialogdismiss()方法中也是执行上述流程。
小结:在不调用DialogsetOnShowListener(OnShowListener listener)方法时Dialog的异步处理是没有用的,和PopupWindow在使用上除了创建的方法不同,系统提供的默认布局不同,是没有本质区别的,如果选择自定义布局的话,两者可以实现的功能也是一样的。

Spinner有两种模式:android:spinnerMode="dropdown"和android:spinnerMode="dialog"而这两种模式分别就是显示一个DropdownPopupDialogPopup
Spinner内部类:

  private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener {        private AlertDialog mPopup;        }

DialogPopup对AlertDialog的封装,这个就是AlertDialog就是android:spinnerMode="dropdown"要显示的控件。

private class DropdownPopup extends ListPopupWindow implements SpinnerPopup(){}

DropdownPopupListPopupWindow 的子类,而ListPopupWindow 又是对PopupWindow的封装。
所以Spinner的显示实际上就是显示一个AlertDialog或者PopupWindow.
Dialog源码分析:http://blog.csdn.net/qq_23547831/article/details/51289456
PopupWindow源码分析:http://blog.csdn.net/qq_23547831/article/details/51322574

0 0
原创粉丝点击