Android Dialog:Dialog和DialogFragment的区别?DialogFragment如何使用?源码解析

news2025/1/8 4:33:49

目录

在这里插入图片描述


一、Dialog和DialogFragment的区别

Android在DialogFragment推出后,就已经不推荐继续使用Dialog,可替换为DialogFragment:

  1. 更好的生命周期管理:DialogFragment能够自动处理Activity的生命周期事件,确保对话框在Activity重建时能够正确恢复。在Activity退出的时候会自动回收Dialog弹窗。
  2. 更高的灵活性:DialogFragment支持复杂的UI和逻辑操作,能够满足更多样化的需求。
  3. 更好的封装性:通过封装对话框的显示逻辑,DialogFragment提高了代码的可重用性和可维护性。
  4. 更好的用户体验:由于DialogFragment能够更好地处理配置更改,因此能够提供更稳定、更流畅的用户体验。

二、Dialog如何使用?

(1)如下是一个最简单的使用方法:

Dialog(this@SettingActivity).show()

(2)当然,我们不可能这样使用,而是会增加布局视图、动画:

<!-- res/layout/dialog_custom.xml -->  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:orientation="vertical"  
    android:padding="16dp">  
  
    <TextView  
        android:id="@+id/textViewMessage"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="这是一个自定义对话框"  
        android:textSize="18sp" />  
  
    <Button  
        android:id="@+id/buttonOk"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="确定" />  
  
</LinearLayout>
// 假设这是Activity中的一个方法  
fun showCustomDialog() {  
    // 创建一个Dialog实例  
    val dialog = Dialog(this)  
  
    // 去除Dialog的标题  
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)  
  
    // 设置Dialog的内容布局  
    dialog.setContentView(R.layout.dialog_custom)  
  
    // 设置Dialog的窗口动画(需要先在res/values/styles.xml中定义动画样式)  
    //dialog.window?.setWindowAnimations(R.style.DialogAnimation)  
  
    // 获取布局中的组件并设置事件监听器  
    val textViewMessage = dialog.findViewById<TextView>(R.id.textViewMessage)  
    val buttonOk = dialog.findViewById<Button>(R.id.buttonOk)  
  
    // 设置按钮的点击事件监听器  
    buttonOk.setOnClickListener {  
        // 关闭Dialog  
        dialog.dismiss()  
    }  
  
    // 显示Dialog  
    dialog.show()  
}

(3)那么如何继承dialog来自定一个dialog呢?

import android.app.Dialog  
import android.content.Context  
import android.os.Bundle  
import android.view.LayoutInflater  
import android.view.View  
import android.view.Window  
import android.widget.Button  
import android.widget.TextView  
  
// 自定义Dialog类  
class CustomDialog(context: Context) : Dialog(context) {  
  
    // 布局中的组件  
    private lateinit var textViewMessage: TextView  
    private lateinit var buttonOk: Button  
    
  	//Dialog的初始化其实就是让我们去初始化自己的视图
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        // 去除标题  
        requestWindowFeature(Window.FEATURE_NO_TITLE)  
        // 设置内容布局  
        setContentView(R.layout.dialog_custom)  
  
        // 初始化布局中的组件  
        textViewMessage = findViewById(R.id.textViewMessage)  
        buttonOk = findViewById(R.id.buttonOk)  
  
        // 设置按钮的点击事件监听器  
        buttonOk.setOnClickListener {  
            // 关闭Dialog  
            dismiss()  
        }  
  
        // (可选)设置Dialog的窗口动画  
        // window?.setWindowAnimations(R.style.DialogAnimation)  
    }  
  
    // 你可以添加更多的方法和属性来扩展你的Dialog  
    // 例如,一个方法来设置消息文本  
    fun setMessage(message: String) {  
        textViewMessage.text = message  
    }  
}  
  
// 在你的Activity或Fragment中这样使用它  
fun showCustomDialog(context: Context) {  
    val customDialog = CustomDialog(context)  
    // (可选)设置消息文本  
    customDialog.setMessage("这是一个自定义对话框")  
    // 显示Dialog  
    customDialog.show()  
}

这个CustomDialog类直接继承了Dialog,并在其onCreate方法中设置了布局、初始化了组件,并设置了监听器。show()其实就是走Dialog的生命周期,然后做初始化工作,注意,show()之后才执行onCreate()。如下源码可以看出:

在这里插入图片描述

在这里插入图片描述


三、Dialog是什么,Window又是什么?

我们可以看一下Dialog的源码。

在这里插入图片描述

Dialog的构造方法中可以看出,Dialog实质上是个Window。

Dialog是Android中用于显示一个浮动窗口的类,这个窗口会覆盖在当前的活动(Activity)或应用程序的顶部。Dialog用于临时显示一些信息给用户,或者要求用户进行某些选择(如确认、选择列表项等)。Dialog可以包含各种控件,如按钮、文本输入框、列表视图等,以便与用户进行交互。

那么Window是什么?

Window是Android中更为抽象的一个概念,它代表了屏幕上的一块矩形区域,用于显示内容。在Android中,几乎所有的UI组件都是基于Window的,包括Activity、Dialog等。Activity实际上是一个特殊的Window,它拥有整个屏幕作为显示区域,并且可以在其上添加各种视图(Views)来构建用户界面。

Dialog与Window的区别:

Dialog与Window:Dialog内部通过PhoneWindow来实现窗口的显示,PhoneWindow是Window的具体实现类。Dialog在创建时会关联一个PhoneWindow对象,并通过这个对象来管理窗口的视图和布局。

WindowManager 是什么?

还有一个WindowManager,WindowManager负责将应用的用户界面显示在屏幕上,并管理窗口的创建、显示、隐藏、更新等操作。Dialog在创建时会关联一个Context(上下文),并通过这个Context获取WindowManager服务,进而与WindowManager绑定,实现窗口的添加和管理。


四、DialogFragment是什么?

DialogFragment 本质上是一个Fragment + Dialog,也就具有Fragment所拥有的生命周期,同时拥有Dialog的特点;在使用时,更容易通过生命周期回调来管理弹窗,对于复杂样式的弹窗,使用DialogFragment更加方便和高效。


五、DialogFragment如何使用

(1)创建xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="880dp"
        android:layout_height="420dp"
        android:layout_gravity="center"
        android:background="@drawable/home_rectangle_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/home_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="120dp"
            android:text="是否立即关机?"
            android:textColor="#576478"
            android:textSize="42sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_start_dev"
            android:layout_width="260dp"
            android:layout_height="100dp"
            android:gravity="center"
            android:text="立即开机"
            android:layout_marginTop="70dp"
            android:textSize="42sp"
            android:textColor="@color/white"
            android:background="@drawable/home_rectangle_blue_background"
            app:layout_constraintEnd_toStartOf="@+id/backstage_guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/home_textview" />

        <TextView
            android:id="@+id/tv_back"
            android:layout_width="260dp"
            android:layout_height="100dp"
            android:layout_marginTop="70dp"
            android:gravity="center"
            android:textColor="#569DF6"
            android:text="取消"
            android:textSize="42sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/backstage_guideline"
            app:layout_constraintTop_toBottomOf="@+id/home_textview" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/backstage_guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5" />


    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

(2)创建一个类继承自DialogFragment,然后给他指定布局文件
在 onCreateView() 方法中,加载弹窗的布局文件。
在 onViewCreated() 方法中,初始化弹窗的控件。

class MyDialogFragment: DialogFragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)

        var view :View = inflater.inflate(R.layout.backstage_dialog_devonoff,container)
        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        var tv :TextView= view.findViewById(R.id.tv_start_dev)
    }
}

(3)在Activity中进行使用。

 val myDialogFragment: MyDialogFragment= MyDialogFragment()
        myDialogFragment.show(supportFragmentManager, "MyDialogFragment")

在这里插入图片描述


六、DialogFragment源码解析

DialogFragment创建的时候,会有两个创建方法:onCreateDialog和onCreateView

class MyDialogFragment:DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return super.onCreateDialog(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return super.onCreateView(inflater, container, savedInstanceState)
    }
}

如果你在onCreateDialog和onCreateView都写了布局,那么会优先使用onCreateDialog里面的。源码这里我们可以看到。如果onCreateDialog不传递一个新的dialog,那么就会使用默认的,而布局,就是从onCreateView里面取,也就是requireView方法。
在这里插入图片描述在这里插入图片描述

如果onCreateDialog不重写,会自动创建一个空白的dialog。view使用的就是oncreateView的:如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2112925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 从入门到实战9(集合)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们通过举例学习了python 中字典的定义及相关操作。今天…

模型训练套路(一)

一、训练完整使用网络模型 import torch import torchvision from torch import nn from torch.utils.data import DataLoaderfrom model1 import* # 此处的引用为此文在实现过程中所解决的问题 train_data torchvision.datasets.CIFAR10(root "../data", trainT…

63、Python之函数高级:装饰器缓存实战,优化递归函数的性能

引言 通过前面的文章&#xff0c;我们已经掌握了Python中常用的装饰器的使用技巧&#xff0c;这篇文章中&#xff0c;我们通过一个装饰器的实战案例&#xff0c;来进一步加深对装饰器的适用场景的理解。 本文的主要内容有&#xff1a; 1、递归函数 2、递归实现斐波那契数列…

AWTK HTML View 控件更新

AWTK HTML View 控件基于 Lite HTML 实现&#xff0c;从最初的版本开始&#xff0c;3 年多过去了&#xff0c;Lite HTML 做了大量的更新&#xff0c;最近抽空将 AWTK HTML View 控件适配到最新版本的 Lite HTML&#xff0c;欢迎大家使用。 AWTK HTML View 控件。HTML View 控件…

SAP B1 基础实操 - 用户定义字段 (UDF)

目录 一、功能介绍 1. 使用场景 2. 操作逻辑 3. 常用定义部分 3.1 主数据 3.2 营销单据 4. 字段设置表单 4.1 字段基础信息 4.2 不同类详细设置 4.3 默认值/必填 二、案例 1 要求 2 操作步骤 一、功能介绍 1. 使用场景 在实施过程中&#xff0c;经常会碰见用户需…

Qt线程使用

嗨嗨嗨&#xff0c;今天又学到了新的知识——线程&#xff0c;这个玩意在项目中使用的频率是非常高的&#xff0c;毕竟电脑的主线程就那么一个&#xff0c;那么这也就是我们为啥要学习线程的原因。比如说&#xff0c;我们们的游戏&#xff0c;如果我们的游戏界面显示的同时我们…

【生日视频制作】奥迪A8提车交车仪式AE模板修改文字软件生成器教程特效素材【AE模板】

奥迪A8提车交车仪式AE模板制作过程软件生成器素材 AE模板套用改图文教程↓↓&#xff1a; 怎么如何做的【生日视频制作】奥迪A8提车交车仪式AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤&#xff1a; 安装AE软件 下载AE模板 把AE模板导入AE软件 修改图片…

PD快充协议方案 及应用场景

快充协议诱骗原理主要依赖于快充协议芯片与供电端&#xff08;如PD充电器&#xff09;之间的握手通信&#xff0c;以申请所需要的电压与电流&#xff0c;确保充电过程安全、快速且高效。这种芯片通过内置的通讯模块与供电端通信&#xff0c;根据设备的实际需求调整输出电压和电…

大路灯护眼灯有必要吗安全吗?性价比高落地护眼灯推荐

大路灯护眼灯有必要吗安全吗&#xff1f;近几年来&#xff0c;随着生活节奏的加快&#xff0c;目前青少年的近视率呈现一个直线上升的趋势&#xff0c;其中占比达到了70%以上&#xff0c;并且最令人意外的是小学生竟然也占着比较大的比重&#xff0c;这一系列的数据不仅表明着近…

苍穹外卖学习笔记(一)

文章目录 开发环境搭建一. 前端环境搭建二. 后端环境搭建1.进入idea项目2.提交git仓库(推送github远程仓库)3.数据库环境搭建4.前后端联调(在源代码中项目已经实现登录功能)nginx反向代理好处: 三. 完善登录功能(md5加密存储)1.首先打开pojo模块中实体类的employee&#xff0c;…

[STL --stack_queue详解]stack、queue,deque,priority_queue,容器适配器

stack stack介绍 1、stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2、stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并提供…

原理图库和PCB库的命名规范及创建封装、使用封装管理器

原理图库 命名规范 原理图中元件值标注规则 注&#xff1a;元件值&#xff08;Component Value&#xff09;就是元件最主要的特征对应的值。 Component value. Most analog components have a value that must be specified by this field (e.g., 2.7 kΩ). Additional disti…

c++数据结构之队列

目录 一、队列的含义 1.队列的使用 2.队列的结构 二、顺序队列的实现 1.队列的定义 2.队列的初始化 3.清空对列 4.队列是否为空 5.获取队列的长度 6.获取头元素的值 7.入队列 8.出队列 9.遍历队列中的值 10.总代码 11.打印结果 三、链表队列的实现 1.队列的…

【Hot100】LeetCode—347. 前 K 个高频元素

目录 1- 思路自定义Node结点 哈希表实现 2- 实现⭐347. 前 K 个高频元素——题解思路 3- ACM实现 原题连接&#xff1a;347. 前 K 个高频元素 1- 思路 自定义Node结点 哈希表实现 ① 自定义 Node 结点&#xff1a; 自定义 Node 结点中有 value 和 cnt 字段&#xff0c;其中…

力扣接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…

html css网页制作

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; HTML 和 CSS 是制作网页的基础。HTML 用于定义网页的结构和内容&#xff0c;CSS 用于设计网页的样式和布局。以下是一个详细的网页制作成品教程&#xff0c;包括 HTML 和 CSS 的基础知识&#xff0c;及如何…

MySQL基础(7)- 多表查询

目录 一、笛卡尔积的错误与正确的多表查询 1.出现笛卡尔积错误 2.正确的多表查询&#xff1a;需要有连接条件 3.查询多个表中都存在的字段 4.SELECT和WHERE中使用表的别名 二、等值连接vs非等值连接、自连接vs非自连接 1.等值连接 vs 非等值连接 2.自连接 vs 非自连…

安卓逆向(之)真机root(红米手机)

概览&#xff1a; 1, 手机解锁 2, 下载官方系统包&#xff0c;推荐线刷包,取出镜像文件 3, magisk工具修补 官方系统包 4, adb&#xff1a;命令对手机刷 root 5, 完成 6, 小米手机解锁 点击 小米手机解锁OEM官方教程 记得数据线连接手机电脑 工具下载 点击 下载adb(电脑操作…

进程间通信-进程池

目录 理解​ 完整代码 完善代码 回收子进程&#xff1a;​ 不回收子进程&#xff1a; 子进程使用重定向优化 理解 #include <iostream> #include <unistd.h> #include <string> #include <vector> #include <sys/types.h>void work(int rfd) {…

Windows下使用cmake编译OpenCV

Windows下使用cmake编译OpenCV cmake下载OpenCV下载编译OpenCV cmake下载 下载地址&#xff1a;https://cmake.org/download/ 下载完成&#xff0c;点击选择路径安装即可 OpenCV下载 下载地址&#xff1a;https://github.com/opencv/opencv/releases/tag/4.8.1因为我们是编译…