Android中Dialog源码解析

我们一般都是在使用AlertDialog,但AlertDialog主要也是继承自Dialog。下面我们来分析分析Dialog源码。

一、Dialog构造函数

public Dialog(Context context) {
    this(context, 0);
}

public Dialog(Context context, int theme) {
    //创建一个Context
    mContext = new ContextThemeWrapper(
        context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);
    //获取一个WindowManager对象
    mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    //创建一个Window对象
    Window w = PolicyManager.makeNewWindow(mContext);
    //将Window对象w赋值给mWindow
    mWindow = w;
    //为Windowd对象设置回调,并且它本身实现了这些回调函数
    w.setCallback(this);
    //为Window对象设置WindowManager对象
    w.setWindowManager(mWindowManager, null, null);
    w.setGravity(Gravity.CENTER);
    //得到当前线程
    mUiThread = Thread.currentThread();
    //创建一个对话框监听Handler
    mListenersHandler = new ListenersHandler(this);
}

从上面我们可以看到Dialog的创建过程其实跟Activity类似,它本质也是一个Window。所以的很多地方跟Activity相似。

二、Dialog生命周期

/**
 * 类似于Activity的onCreate函数,可以在这个方法中进行Dialog的一些初始化操作
 * 包括调用setContentView方法
 */
protected void onCreate(Bundle savedInstanceState) {
}

/**
 * 当对话框启动的时候被调用.
 */
protected void onStart() {
}

/**
 * 当对话框停止的时候被调用.
 */
protected void onStop() {
}

三、对话框的显示

public void show() {
    //首先判断对话框是否显示
    if (mShowing) {
        if (mDecor != null) {
            mDecor.setVisibility(View.VISIBLE);
        }
        return;
    }
    /*判断对话框是否创建过,如果没有创建过
    * 在dispatchOnCreate里面就会回调onCreate函数
    */
    if (!mCreated) {
        dispatchOnCreate(null);
    }
    //回调onStart函数
    onStart();
    //获取Window对象总的DecorView,如果调用了setContentView就会创建DecorView
    mDecor = mWindow.getDecorView();
    //下面就会获取布局的一些属性
    WindowManager.LayoutParams l = mWindow.getAttributes();
    if ((l.softInputMode
            & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
        WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
        nl.copyFrom(l);
        nl.softInputMode |=
                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
        l = nl;
    }

    try {
        //将DecorView添加到WindowManager中,这些就会显示了
        mWindowManager.addView(mDecor, l);
        mShowing = true;

        sendShowMessage();
    } finally {
    }
}

从上面可以看到它是将Window中的DecorView添加到了WindowManager中来进行显示的。

四、Dialog的销毁

public void dismiss() {
    /*判断当前线程释放为UI线程
    *如果不是UI线程,则将mDismissAction到UI线程中执行
    *如果是UI线程,则直接执行mDismissAction的run方法
    *也就是销毁操作在mDismissAction的run方法中
    */
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(mDismissAction);
    } else {
        mDismissAction.run();
    }
}

下面我们来看看mDismissAction对象的类:

private final Runnable mDismissAction = new Runnable() {
    public void run() {
        dismissDialog();
    }
};  

private void dismissDialog() {
    //首先判断Decor是否存在以及是否显示
    if (mDecor == null || !mShowing) {
        return;
    }
    //将DecorView从WindowManger对象中移除
    try {
        mWindowManager.removeView(mDecor);
    } finally {
        mDecor = null;
        mWindow.closeAllPanels();
        //回调onStop方法
        onStop();
        mShowing = false;

        sendDismissMessage();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android,可以通过点击视图获取Dialog的位置信息并对其进行定位。可以使用getFragmentCenterLocationOnScreen()方法来获取Dialog的位置信息。该方法通过获取View的位置信息,计算得到Dialog心位置坐标,并返回一个包含位置信息的Rect对象。 具体实现可以参考以下代码: ``` private Rect getFragmentCenterLocationOnScreen() { int[] location = new int = location + fragment_width/2; location = location + fragment_height/2; rect = new Rect(location + fragment_width, location + fragment_height); return rect; } ``` 这样,通过调用getFragmentCenterLocationOnScreen()方法,可以获取到Dialog的位置信息,并将其用于定位Dialog的位置。 请注意,这只是一种实现的思路,具体的实现方式还需要根据具体的需求和代码结构进行相应的调整和修改。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Android-随意变化的气泡布局Dialog根据点击View的位置定位它的位置Dialog可定制方向等](https://download.csdn.net/download/weixin_39840387/11527304)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Android里设置Dialog位置](https://blog.csdn.net/wujiang_android/article/details/101031471)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Android自动化测试—操作对话框(Dialog)上面的控件](https://download.csdn.net/download/weixin_38597970/16056345)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值