🐳 《Android》 安卓开发教程 -体检 必填校验质控 弹窗

一、什么是自定义弹窗

安卓的自定义弹窗(Custom Dialog) ,是指开发者不使用系统默认样式的弹窗(如 AlertDialog),而是通过自己定义布局、逻辑和样式来创建一个具有个性化外观和行为的弹窗。


📌 为什么要用自定义弹窗?

系统提供的 AlertDialog 虽然简单易用,但样式固定、功能受限。如果你想实现如下需求时就需要自定义弹窗:

  • 弹窗中有复杂布局(比如图片、输入框、按钮等)
  • 需要适配品牌风格、主题
  • 实现动画、全屏或圆角弹窗等特殊效果
  • 更灵活的交互逻辑

二、实践步骤

2.1 自定义弹窗样式

编写 res/layout/dialog_health_save.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@drawable/app_dialog_bg"
    android:orientation="vertical"
    >

    <!-- 标题 -->
    <TextView
        android:id="@+id/tvDialogTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:gravity="left"
        android:padding="10dp"
        android:text="未填写内容:"
        android:textColor="@color/status_blue"
        android:textSize="20sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/_999" />

    <!-- 可滑动的未保存项区域 -->
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="8"
    android:fillViewport="true"
    android:maxHeight="300dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:orientation="vertical">
        
        <!--般状况-->
        <LinearLayout
            android:id="@+id/tvGeneralConditionContextLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >
                <TextView
                    android:id="@+id/tvGeneralConditionContext"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="一般状况:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right">
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/tvGeneralConditionContextEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>




        </LinearLayout>



        <!--生活方式-->
        <LinearLayout
            android:id="@+id/tvLifestyleContextLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >
                <TextView
                    android:id="@+id/tvLifestyleContext"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="生活方式:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right"
                >
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/tvLifestyleContextEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>




        </LinearLayout>


        <!--症状-->
        <LinearLayout
            android:id="@+id/tvSymptomContentLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >
                <TextView
                    android:id="@+id/tvSymptomContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="症状:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right"
                >
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/tvSymptomEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>




        </LinearLayout>




        <!--脏器功能-->
        <LinearLayout
            android:id="@+id/tvOrganFunctionContextLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >
                <TextView
                    android:id="@+id/tvOrganFunctionContext"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="脏器功能:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right"
                >
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/tvOrganFunctionContextEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>




        </LinearLayout>

        <!--查体-->
        <LinearLayout
            android:id="@+id/physicalExaminationLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >
                <TextView
                    android:id="@+id/physicalExamination"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="查体:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right"
                >
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/physicalExaminationEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>




        </LinearLayout>

        <!--辅助检查-->
        <LinearLayout
            android:id="@+id/auxiliaryExamLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >
                <TextView
                    android:id="@+id/auxiliaryExam"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="赋值检查:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right"
                >
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/auxiliaryExamEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>




        </LinearLayout>




        <!--现存健康问题-->
        <LinearLayout
            android:id="@+id/tvCurrentHealthIssuesContextLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >

                <TextView
                    android:id="@+id/tvCurrentHealthIssuesContext"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="现存健康问题:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right"
                >
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/tvCurrentHealthIssuesContextEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>

        </LinearLayout>

        <!--更多-->
        <LinearLayout
            android:id="@+id/tvMoreContextLine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:visibility="gone"
            >


            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="9"
                >
                <TextView
                    android:id="@+id/tvMoreContext"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="更多:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写\n基本信息:人群分类、联系电话、联系人姓名、联系人电话、现住址、户籍地址未填写"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="right"
                >
                <!-- 确定按钮 -->
                <Button
                    android:id="@+id/tvMoreContextEdit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?android:attr/selectableItemBackground"
                    android:text="编辑"
                    android:textColor="@color/status_blue"
                    android:textSize="18sp" />

            </LinearLayout>




        </LinearLayout>
















        </LinearLayout>

    </ScrollView>

    <View
        android:layout_width="match_parent"
        android:paddingTop="5dp"
        android:layout_height="1dp"
        android:background="@color/_999" />

    <!-- 确定按钮 -->
    <Button
        android:id="@+id/btnDialogCancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/selectableItemBackground"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:text="确认"
        android:textColor="@color/status_blue"
        android:textSize="30sp" />
</LinearLayout>

2.2 编写质控判空方法

java 复制代码
package com.imindbot.medicalinformation.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.google.gson.Gson;
import com.imindbot.medicalinformation.data.param.FamilyBedHistoryParam;
import com.imindbot.medicalinformation.data.param.HealthCheckUpSaveParam;
import com.imindbot.medicalinformation.data.param.HospitalizationHistoryParam;
import com.imindbot.medicalinformation.data.param.MedicationParam;
import com.imindbot.medicalinformation.data.param.NonImmunizationVaccinationHistoryParam;
import com.imindbot.medicalinformation.data.vo.HealthSaveEmptyVo;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
// 引入集合工具类,方便检查列表是否为空


import java.text.SimpleDateFormat;
import java.util.*;

/**
 * author:
 * date:2025-03-31 9:38
 * 服务类,用于检查健康体检保存参数中的空值项。
 **/
public class NullCheckServiceNew {

    /**
     * 检查健康检查表单中的空值项。
     *
     * @param
     * @return 一个 HealthSaveEmptyVo 对象,包含了各个部分未填写字段的提示信息。
     */
    public static HealthSaveEmptyVo healthCheckEmpty(HealthCheckUpSaveParam entity) {
//        Gson gson = new Gson();
//
//        HealthCheckUpSaveParam entity = gson.fromJson(e, HealthCheckUpSaveParam.class);
        HealthSaveEmptyVo result = new HealthSaveEmptyVo();
        if (entity == null) {
            return null;
        }

        List<String> generalConditionEmptyFields = new ArrayList<>(); // 一般状况
        List<String> lifestyleEmptyFields = new ArrayList<>();        // 生活方式
        List<String> symptomEmptyFields = new ArrayList<>();          // 症状
        List<String> organFunctionEmptyFields = new ArrayList<>();    // 脏器功能
        List<String> physicalExamEmptyFields = new ArrayList<>();     // 查体
        List<String> existingProblemsEmptyFields = new ArrayList<>(); // 现存健康问题
        List<String> moreInfoEmptyFields = new ArrayList<>();         // 更多信息(住院史等)
        List<String> auxiliaryExamEmptyFields = new ArrayList<>(); //辅助检查

        // 一般状况
        if (ObjectUtils.isEmpty(entity.getTemperature())) { // 体温
            generalConditionEmptyFields.add("体温");
        }
        if (ObjectUtils.isEmpty(entity.getBreathingRate())) { // 呼吸频率
            generalConditionEmptyFields.add("呼吸频率");
        }
        // 血压需要同时看收缩压和舒张压,左右两侧都看
        if (ObjectUtils.isEmpty(entity.getLeftSystolic()) || ObjectUtils.isEmpty(entity.getLeftDiastolic())) { // 左侧血压
            generalConditionEmptyFields.add("左侧血压");
        }
        if (ObjectUtils.isEmpty(entity.getRightSystolic()) || ObjectUtils.isEmpty(entity.getRightDiastolic())) { // 右侧血压
            generalConditionEmptyFields.add("右侧血压");
        }
        if (ObjectUtils.isEmpty(entity.getPulse())) { // 脉率
            generalConditionEmptyFields.add("脉率");
        }
        if (ObjectUtils.isEmpty(entity.getHeight())) { // 身高
            generalConditionEmptyFields.add("身高");
        }
        if (ObjectUtils.isEmpty(entity.getWeight())) { // 体重
            generalConditionEmptyFields.add("体重");
        }
        if (ObjectUtils.isEmpty(entity.getWaist())) { // 腰围
            generalConditionEmptyFields.add("腰围");
        }
        if (StringUtils.isNotBlank(entity.getBirthday())) {
            int age = calculateAge(entity.getBirthday());
            if (age >= 65) {
                if (StringUtils.isBlank(entity.getHealthSelfRating())) { // 健康状态自我评估
                    generalConditionEmptyFields.add("健康状态自我评估");
                }
                if (StringUtils.isBlank(entity.getElderlySelfCareScore())) { // 生活自理能力 (老年人)
                    generalConditionEmptyFields.add("生活自理能力"); // 注意:字段名叫 elderlySelfCareScore,可能只对老年人有意义
                }
                if (StringUtils.isBlank(entity.getCognition())) { // 认知功能
                    generalConditionEmptyFields.add("认知功能");
                }
            }
        }


        // 生活方式
        if (ObjectUtils.isEmpty(entity.getWeeklyExercises())) { // 每次锻炼时间
            lifestyleEmptyFields.add("锻炼频率");
        }
        if (ObjectUtils.isEmpty(entity.getExerciseTime())) { // 每次锻炼时间
            lifestyleEmptyFields.add("每次锻炼时间");
        }
        if (StringUtils.isBlank(entity.getExerciseYears())) { // 坚持锻炼时间
             lifestyleEmptyFields.add("坚持锻炼时间");
        }
        if (StringUtils.isBlank(entity.getExerciseType())) { // 锻炼方式
            lifestyleEmptyFields.add("锻炼方式");
        }
        // 吸烟情况需要综合判断
        if (StringUtils.isBlank(entity.getSmoking())) { // 吸烟情况(从不、已戒烟、吸烟)
             lifestyleEmptyFields.add("吸烟情况");
        } else if ("吸烟".equals(entity.getSmoking())) { // 如果选择吸烟,才检查下面两个
            if (ObjectUtils.isEmpty(entity.getDailySmoke())) { // 日吸烟量
                lifestyleEmptyFields.add("日吸烟量");
            }
            if (ObjectUtils.isEmpty(entity.getStartSmokingAge())) { // 开始吸烟年龄
                lifestyleEmptyFields.add("开始吸烟年龄");
            }
        } else if ("已戒烟".equals(entity.getSmoking())) { // 如果选择已戒烟,才检查戒烟年龄
            if (ObjectUtils.isEmpty(entity.getQuitSmokingAge())) { // 戒烟年龄
                lifestyleEmptyFields.add("戒烟年龄");
            }
             if (ObjectUtils.isEmpty(entity.getStartSmokingAge())) { // 开始吸烟年龄也可能需要填
                lifestyleEmptyFields.add("开始吸烟年龄");
            }
        }
        // 饮酒情况类似
        if (StringUtils.isBlank(entity.getDrinkingFrequency())) { // 饮酒频率
            lifestyleEmptyFields.add("饮酒频率");
        } else if (!"从不".equals(entity.getDrinkingFrequency())) { // 如果不是从不饮酒
            if (ObjectUtils.isEmpty(entity.getDailyDrinkAmount())) { // 日饮酒量
                lifestyleEmptyFields.add("日饮酒量");
            }
            if (ObjectUtils.isEmpty(entity.getStartDrinkingAge())) { // 开始饮酒年龄
                lifestyleEmptyFields.add("开始饮酒年龄");
            }
            // 检查饮酒种类 (优先检查 List,如果 List 为空再看 String)
            if (CollectionUtil.isEmpty(entity.getDrinkTypeList()) && StringUtils.isBlank(entity.getDrinkType())) {
                 lifestyleEmptyFields.add("饮酒种类");
            }
            // 检查是否戒酒和戒酒年龄
             if (StringUtils.isBlank(entity.getQuitDrinking())) { // 是否戒酒
                 lifestyleEmptyFields.add("是否戒酒");
             } else if ("是".equals(entity.getQuitDrinking())) { // 如果选择是戒酒
                if (ObjectUtils.isEmpty(entity.getQuitDrinkingAge())) { // 戒酒年龄
                     lifestyleEmptyFields.add("戒酒年龄");
                }
            }
        }


        // 症状
        // 如果 symptomList 为空,并且 symptomOther 也为空,则认为未填写
        if (CollectionUtil.isEmpty(entity.getSymptomList()) && StringUtils.isBlank(entity.getSymptomOther())) {
            if (StringUtils.isBlank(entity.getSymptom())) {
                 symptomEmptyFields.add("症状");
            }
        }

        // 脏器功能
        //口唇
        if (ObjectUtils.isEmpty(entity.getLips())) {
            organFunctionEmptyFields.add("口唇");
        }
        //咽部
        if (ObjectUtils.isEmpty(entity.getThroatList())) {
            organFunctionEmptyFields.add("咽部");
        }

        // 齿列 (优先检查 List)
        if (CollectionUtil.isEmpty(entity.getTeethAlignmentList()) && StringUtils.isBlank(entity.getTeethAlignment())) {
             organFunctionEmptyFields.add("齿列");
        } else {
            // 如果齿列选了"缺齿",检查缺齿部位
            boolean needCheckMissing = (entity.getTeethAlignmentList() != null && entity.getTeethAlignmentList().contains("缺齿"))
                                      || "缺齿".equals(entity.getTeethAlignment()); // 假设单选或多选都可能包含
            if (needCheckMissing && CollectionUtil.isEmpty(entity.getMissingTeethList()) && StringUtils.isBlank(entity.getMissingTeeth())) {
                 organFunctionEmptyFields.add("缺齿部位");
            }
            // 如果齿列选了"龋齿",检查龋齿部位
            boolean needCheckCavities = (entity.getTeethAlignmentList() != null && entity.getTeethAlignmentList().contains("龋齿"))
                                      || "龋齿".equals(entity.getTeethAlignment());
            if (needCheckCavities && CollectionUtil.isEmpty(entity.getCavitiesList()) && StringUtils.isBlank(entity.getCavities())) {
                 organFunctionEmptyFields.add("龋齿部位");
            }
             // 如果齿列选了"义齿",检查义齿部位
            boolean needCheckDentures = (entity.getTeethAlignmentList() != null && entity.getTeethAlignmentList().contains("义齿(假牙)"))
                                      || "义齿(假牙)".equals(entity.getTeethAlignment());
             if (needCheckDentures && CollectionUtil.isEmpty(entity.getDenturesList()) && StringUtils.isBlank(entity.getDentures())) {
                 organFunctionEmptyFields.add("义齿部位");
            }
        }
        // 视力
         if (CollectionUtil.isEmpty(entity.getVisionList()) && StringUtils.isBlank(entity.getVision())) {
            organFunctionEmptyFields.add("视力");
        }
         // 听力
        if (StringUtils.isBlank(entity.getHearing())) {
             organFunctionEmptyFields.add("听力");
        }
        if (StringUtils.isBlank(entity.getMotorFunction())) {
            organFunctionEmptyFields.add("运动功能");
        }
        // 查体
        if (isEffectivelyBlank(entity.getSkin()) && isEffectivelyBlank(entity.getSkinOther())) { // 皮肤
            physicalExamEmptyFields.add("皮肤");
        }
        if (isEffectivelyBlank(entity.getSclera()) && isEffectivelyBlank(entity.getScleraOther())) { // 巩膜
            physicalExamEmptyFields.add("巩膜");
        }
        if (CollectionUtil.isEmpty(entity.getLymphNodesList()) && isEffectivelyBlank(entity.getLymphNodes()) && isEffectivelyBlank(entity.getLymphNodesOther())) { // 淋巴结
            physicalExamEmptyFields.add("淋巴结");
        }
        if (isEffectivelyBlank(entity.getBarrelChest())) { // 肺部桶状胸
            physicalExamEmptyFields.add("肺部桶状胸");
        }
         if (isEffectivelyBlank(entity.getBreathSounds()) && isEffectivelyBlank(entity.getBreathSoundsOther())) { // 肺部呼吸音
            physicalExamEmptyFields.add("肺部呼吸音");
        }
        if (CollectionUtil.isEmpty(entity.getRalesList()) && isEffectivelyBlank(entity.getRales()) && isEffectivelyBlank(entity.getRalesListOther())) { // 肺部啰音
            physicalExamEmptyFields.add("肺部啰音");
        }
        if (isEffectivelyBlank(entity.getHeartRhythm())) { // 心律
            physicalExamEmptyFields.add("心律");
        }
         if (isEffectivelyBlank(entity.getHeartMurmur()) && isEffectivelyBlank(entity.getHeartMurmurOther())) { // 心脏杂音
            physicalExamEmptyFields.add("心脏杂音");
        }

         if (isEffectivelyBlank(entity.getAbdominalTenderness()) && isEffectivelyBlank(entity.getAbdominalTendernessOther())) { // 腹部压痛
             physicalExamEmptyFields.add("腹部压痛");
         }
         if (isEffectivelyBlank(entity.getAbdominalMass()) && isEffectivelyBlank(entity.getAbdominalMassOther())) { // 腹部包块
             physicalExamEmptyFields.add("腹部包块");
         }
         if (isEffectivelyBlank(entity.getHepatomegaly()) && isEffectivelyBlank(entity.getHepatomegalyOther())) { // 腹部肝大
             physicalExamEmptyFields.add("腹部肝大");
         }
         if (isEffectivelyBlank(entity.getSplenomegaly()) && isEffectivelyBlank(entity.getSplenomegalyOther())) { // 腹部脾大
             physicalExamEmptyFields.add("腹部脾大");
         }
         if (isEffectivelyBlank(entity.getShiftingDullness()) && isEffectivelyBlank(entity.getShiftingDullnessOther())) { // 移动性浊音
             physicalExamEmptyFields.add("移动性浊音");
         }
         if (CollectionUtil.isEmpty(entity.getDorsalPulsePartList()) && isEffectivelyBlank(entity.getDorsalPulse())) { // 足背动脉搏动
             physicalExamEmptyFields.add("足背动脉搏动");
         }


        //  现存健康问题
        // 如果对应的 List 和 Other 字段都为空,则认为未填写
        if (CollectionUtil.isEmpty(entity.getCerebrovascularDiseaseList()) && (StringUtils.isBlank(entity.getCerebrovascularDiseaseOther())||entity.getCerebrovascularDiseaseOther().equals("null") )) {
            existingProblemsEmptyFields.add("脑血管疾病");
        }
        if (CollectionUtil.isEmpty(entity.getKidneyDiseaseList()) && (StringUtils.isBlank(entity.getKidneyDiseaseOther())||entity.getKidneyDiseaseOther().equals("null") )) {
            existingProblemsEmptyFields.add("肾脏疾病");
        }
         if (CollectionUtil.isEmpty(entity.getHeartDiseaseList()) && (StringUtils.isBlank(entity.getHeartDiseaseOther())||entity.getHeartDiseaseOther().equals("null") )) {
            existingProblemsEmptyFields.add("心脏疾病");
        }
        if (CollectionUtil.isEmpty(entity.getVascularDiseaseList()) && (StringUtils.isBlank(entity.getVascularDiseaseOther())||entity.getVascularDiseaseOther().equals("null") )) {
            existingProblemsEmptyFields.add("血管疾病");
        }
        if (CollectionUtil.isEmpty(entity.getEyeDiseaseList()) && (StringUtils.isBlank(entity.getEyeDiseaseOther())||entity.getEyeDiseaseOther().equals("null") )) {
            existingProblemsEmptyFields.add("眼部疾病");
        }
        // 神经系统疾病 和 其他系统疾病 在 HealthCheckup 中有 String 字段,在 Param 中只有 Other 字段
        if (StringUtils.isBlank(entity.getNervousSystemDisease()) && (StringUtils.isBlank(entity.getNervousSystemDiseaseOther())||entity.getNervousSystemDiseaseOther().equals("null") )) {
             existingProblemsEmptyFields.add("神经系统疾病");
        }
        if (CollectionUtil.isEmpty(entity.getOtherSystemDiseaseList()) && (StringUtils.isBlank(entity.getOtherSystemDiseaseOther())||entity.getOtherSystemDiseaseOther().equals("null") )) {
            existingProblemsEmptyFields.add("其他系统疾病");
        }


        // 更多信息
        // 检查住院史列表是否为空
        List<String> hospital = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(entity.getHospitalHistoryList())) {
            for (HospitalizationHistoryParam param : entity.getHospitalHistoryList()) {
                if (ObjectUtils.isEmpty(param.getMedicalInstitutionName())) {
                    hospital.add("医疗机构名称");
                }
                if (ObjectUtils.isEmpty(param.getReason())) {
                    hospital.add("原因");
                }
                if (ObjectUtils.isEmpty(param.getAdmissionDate())) {
                    hospital.add("入院日期");
                }
                if (ObjectUtils.isEmpty(param.getDischargeDate())) {
                    hospital.add("出院日期");
                }
                if (ObjectUtils.isEmpty(param.getMedicalRecordNumber())) {
                    hospital.add("病案号");
                }
                if (ObjectUtils.isNotEmpty(hospital)){
                    moreInfoEmptyFields.add("住院史:" + String.join("、",hospital) + "未填写");
                    break;
                }
            }

        }
        // 检查家庭病床史列表是否为空
        List<String> familyBed = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(entity.getFamilyBedHistoryList())) {
            for (FamilyBedHistoryParam param : entity.getFamilyBedHistoryList()) {
                if (ObjectUtils.isEmpty(param.getMedicalInstitutionName())) {
                    familyBed.add("医疗机构名称");
                }
                if (ObjectUtils.isEmpty(param.getReason())) {
                    familyBed.add("原因");
                }
                if (ObjectUtils.isEmpty(param.getBedEstablishedDate())) {
                    familyBed.add("建床日期");
                }
                if (ObjectUtils.isEmpty(param.getBedRemovedDate())) {
                    familyBed.add("撤床日期");
                }
                if (ObjectUtils.isEmpty(param.getMedicalRecordNumber())) {
                    familyBed.add("病案号");
                }
                if (ObjectUtils.isNotEmpty(familyBed)){
                    moreInfoEmptyFields.add("家庭病床史:" + String.join("、",familyBed) + "未填写");
                    break;
                }
            }
        }
        // 检查非免疫规划接种史列表是否为空
        List<String> nonVaccine = new ArrayList<>();
         if (CollectionUtil.isNotEmpty(entity.getNonVaccineHistoryList())) {
             for (NonImmunizationVaccinationHistoryParam param : entity.getNonVaccineHistoryList()) {
                 if (ObjectUtils.isEmpty(param.getVaccineName())) {
                     nonVaccine.add("疫苗名称");
                 }
                 if (ObjectUtils.isEmpty(param.getVaccinationDate())) {
                     nonVaccine.add("接种日期");
                 }
                 if (ObjectUtils.isEmpty(param.getVaccinationSite())) {
                     nonVaccine.add("接种结构");
                 }
                 if (ObjectUtils.isNotEmpty(nonVaccine)){
                     moreInfoEmptyFields.add("非免疫规划接种史:" + String.join("、",nonVaccine) + "未填写");
                     break;
                 }
             }
        }
        // 检查用药情况列表是否为空
        List<String> medication = new ArrayList<>();
         if (CollectionUtil.isNotEmpty(entity.getMedicationList())) {
             for (MedicationParam param : entity.getMedicationList()) {
                 if (ObjectUtils.isEmpty(param.getMedicationName())) {
                     medication.add("药品名称");
                 }
                 if (ObjectUtils.isEmpty(param.getMedicationTime())) {
                     medication.add("用药时间");
                 }
                 if (ObjectUtils.isEmpty(param.getFrequencyDay())) {
                     medication.add("频次");
                 }
                 if (ObjectUtils.isEmpty(param.getDosagePerDay())) {
                     medication.add("每次用量");
                 }
                 if (ObjectUtils.isNotEmpty(medication)){
                     moreInfoEmptyFields.add("用药情况:" + String.join("、",medication) + "未填写");
                     break;
                 }
             }
        }

         // 辅助检查
        // 血常规检查
        if (isEffectivelyBlank(entity.getRandomGlucose())) { // 随机血糖
            auxiliaryExamEmptyFields.add("随机血糖");
        }
        if (isEffectivelyBlank(entity.getFastingBloodGlucose())) { // 空腹血糖
            auxiliaryExamEmptyFields.add("空腹血糖");
        }

        if (isEffectivelyBlank(entity.getPro())) { // 尿蛋白
            auxiliaryExamEmptyFields.add("尿蛋白");
        }
        if (isEffectivelyBlank(entity.getSug())) { // 尿糖
            auxiliaryExamEmptyFields.add("尿糖");
        }
        if (isEffectivelyBlank(entity.getKet())) { // 尿酮体
            auxiliaryExamEmptyFields.add("尿酮体");
        }
        if (isEffectivelyBlank(entity.getBld())) { // 尿潜血
            auxiliaryExamEmptyFields.add("尿潜血");
        }



        // 心电图检查
        if (isEffectivelyBlank(entity.getEcgResult())) { // 心电图结果
            auxiliaryExamEmptyFields.add("心电图结果");
        }
        if (isEffectivelyBlank(entity.getEcgExaDoctor())) { // 心电图检查医生
            auxiliaryExamEmptyFields.add("心电图检查医生");
        }

        // 腹部B超检查
        if (isEffectivelyBlank(entity.getAbusResult())) { // 腹部B超结果
            auxiliaryExamEmptyFields.add("腹部B超结果");
        }
        if (isEffectivelyBlank(entity.getAbusExaDoctor())) { // 腹部B超检查医生
            auxiliaryExamEmptyFields.add("腹部B超检查医生");
        }


        if (!generalConditionEmptyFields.isEmpty()) {
            result.setGeneralCondition("一般状况:" + String.join("、", generalConditionEmptyFields) + "未填写");
        }
        if (!lifestyleEmptyFields.isEmpty()) {
            result.setLifestyle("生活方式:" + String.join("、", lifestyleEmptyFields) + "未填写");
        }
        if (!symptomEmptyFields.isEmpty()) {
            result.setSymptoms("症状:" + String.join("、", symptomEmptyFields) + "未填写");
        }
        if (!organFunctionEmptyFields.isEmpty()) {
            result.setOrganFunction("脏器功能:" + String.join("、", organFunctionEmptyFields) + "未填写");
        }
        if (!physicalExamEmptyFields.isEmpty()) {
            result.setPhysicalExamination("查体:" + String.join("、", physicalExamEmptyFields) + "未填写");
        }
        if (!existingProblemsEmptyFields.isEmpty()) {
            result.setExistingHealthIssues("现存健康问题:" + String.join("、", existingProblemsEmptyFields) + "未填写");
        }
        if (!moreInfoEmptyFields.isEmpty()) {
            result.setAdditionalInfo("更多:" + String.join(",", moreInfoEmptyFields));
        }
        if (!auxiliaryExamEmptyFields.isEmpty()) {
            result.setAuxiliaryExam("辅助检查:" + String.join("、", auxiliaryExamEmptyFields));
        }

        return  result;
//        return gson.toJson(result);
    }
    // 计算年龄
    private static  int calculateAge(String birthDate) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date birth = sdf.parse(birthDate);
            Calendar birthCalendar = Calendar.getInstance();
            birthCalendar.setTime(birth);
            Calendar now = Calendar.getInstance();
            int age = now.get(Calendar.YEAR) - birthCalendar.get(Calendar.YEAR);
            if (now.get(Calendar.MONTH) < birthCalendar.get(Calendar.MONTH) ||
                    (now.get(Calendar.MONTH) == birthCalendar.get(Calendar.MONTH) &&
                            now.get(Calendar.DAY_OF_MONTH) < birthCalendar.get(Calendar.DAY_OF_MONTH))) {
                age--;
            }
            return age;
        } catch (java.text.ParseException e) {
            return -1;
        }
    }

    private static boolean isEffectivelyBlank(String str) {
        return StringUtils.isBlank(str) || "null".equalsIgnoreCase(str.trim());
    }
}

2.3 监控保存按钮

java 复制代码
binding.llTitleBar.tvSave.setOnClickListener(view -> {```
//提示未保存项
showHealthSaveDialog(view,paramDiffPanKong);
}
 public void showHealthSaveDialog(View view, HealthCheckUpSaveParam paramDiffPanKong) {

        // 创建 AlertDialog.Builder
        AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());

        // 通过 LayoutInflater 加载自定义布局
        LayoutInflater inflater = LayoutInflater.from(view.getContext());
        View dialogView = inflater.inflate(R.layout.dialog_health_save, null);

        // 绑定控件
        TextView tvDialogTitle = dialogView.findViewById(R.id.tvDialogTitle);
        Button btnDialogCancel = dialogView.findViewById(R.id.btnDialogCancel);

        TextView tvGeneralConditionContext = dialogView.findViewById(R.id.tvGeneralConditionContext);
        View tvGeneralConditionContextLine = dialogView.findViewById(R.id.tvGeneralConditionContextLine);
        View tvGeneralConditionContextEdit = dialogView.findViewById(R.id.tvGeneralConditionContextEdit);

        TextView tvLifestyleContext = dialogView.findViewById(R.id.tvLifestyleContext);
        View tvLifestyleContextLine = dialogView.findViewById(R.id.tvLifestyleContextLine);
        View tvLifestyleContextEdit = dialogView.findViewById(R.id.tvLifestyleContextEdit);

        TextView tvSymptomContent = dialogView.findViewById(R.id.tvSymptomContent);
        View tvSymptomContentLine = dialogView.findViewById(R.id.tvSymptomContentLine);
        View tvSymptomEdit = dialogView.findViewById(R.id.tvSymptomEdit);

        TextView tvOrganFunctionContext = dialogView.findViewById(R.id.tvOrganFunctionContext);
        View tvOrganFunctionContextLine = dialogView.findViewById(R.id.tvOrganFunctionContextLine);
        View tvOrganFunctionContextEdit = dialogView.findViewById(R.id.tvOrganFunctionContextEdit);

        TextView physicalExaminationView = dialogView.findViewById(R.id.physicalExamination);
        View physicalExaminationLine = dialogView.findViewById(R.id.physicalExaminationLine);
        View physicalExaminationEdit = dialogView.findViewById(R.id.physicalExaminationEdit);


        TextView auxiliaryExamView = dialogView.findViewById(R.id.auxiliaryExam);
        View auxiliaryExamLine = dialogView.findViewById(R.id.auxiliaryExamLine);
        View auxiliaryExamEdit = dialogView.findViewById(R.id.auxiliaryExamEdit);

        TextView tvCurrentHealthIssuesContext = dialogView.findViewById(R.id.tvCurrentHealthIssuesContext);
        View tvCurrentHealthIssuesContextLine = dialogView.findViewById(R.id.tvCurrentHealthIssuesContextLine);
        View tvCurrentHealthIssuesContextEdit = dialogView.findViewById(R.id.tvCurrentHealthIssuesContextEdit);

        TextView tvmore = dialogView.findViewById(R.id.tvMoreContext); // 新增现存健康问题
        View tvMoreContextLine = dialogView.findViewById(R.id.tvMoreContextLine);
        View tvMoreContextEdit = dialogView.findViewById(R.id.tvMoreContextEdit);

        HealthSaveEmptyVo healthSaveEmptyVo = HealthJiaoYanUtils.getHealthSaveEmptyVo(paramDiffPanKong);
        if (healthSaveEmptyVo == null ||
                ((healthSaveEmptyVo.generalCondition ==null || healthSaveEmptyVo.generalCondition.isBlank()) &&
                        (healthSaveEmptyVo.lifestyle ==null || healthSaveEmptyVo.lifestyle.isBlank()) &&
                        (healthSaveEmptyVo.symptoms ==null || healthSaveEmptyVo.symptoms.isBlank()) &&
                        (healthSaveEmptyVo.organFunction ==null || healthSaveEmptyVo.organFunction.isBlank()) &&
                        (healthSaveEmptyVo.physicalExamination ==null || healthSaveEmptyVo.physicalExamination.isBlank()) &&
                        (healthSaveEmptyVo.existingHealthIssues ==null || healthSaveEmptyVo.existingHealthIssues.isBlank()) &&
                        (healthSaveEmptyVo.auxiliaryExam ==null || healthSaveEmptyVo.auxiliaryExam.isBlank()) &&
                        (healthSaveEmptyVo.additionalInfo ==null || healthSaveEmptyVo.additionalInfo.isBlank())
                )
        ){
            return;
        }

        //-般状况 generalCondition tvGeneralConditionContext tvGeneralConditionContextLine
        if (healthSaveEmptyVo.generalCondition != null && !healthSaveEmptyVo.generalCondition.isBlank()){
            tvGeneralConditionContext.setText(healthSaveEmptyVo.generalCondition);
            tvGeneralConditionContextLine.setVisibility(View.VISIBLE);
        }
        //生活方式 lifestyle tvLifestyleContext tvLifestyleContextLine
        if (healthSaveEmptyVo.lifestyle != null && !healthSaveEmptyVo.lifestyle.isBlank()){
            tvLifestyleContext.setText(healthSaveEmptyVo.lifestyle);
            tvLifestyleContextLine.setVisibility(View.VISIBLE);
        }
        //症状 symptoms tvSymptom tvSymptomContentLine
        if (healthSaveEmptyVo.symptoms != null && !healthSaveEmptyVo.symptoms.isBlank()){
            tvSymptomContent.setText(healthSaveEmptyVo.symptoms);
            tvSymptomContentLine.setVisibility(View.VISIBLE);
        }
        //脏器功能 organFunction tvOrganFunctionContext tvOrganFunctionContextLine
        if (healthSaveEmptyVo.organFunction != null && !healthSaveEmptyVo.organFunction.isBlank()){
            tvOrganFunctionContext.setText(healthSaveEmptyVo.organFunction);
            tvOrganFunctionContextLine.setVisibility(View.VISIBLE);
        }
        //查体 physicalExamination physicalExaminationView physicalExaminationLine
        if (healthSaveEmptyVo.physicalExamination != null && !healthSaveEmptyVo.physicalExamination.isBlank()){
            physicalExaminationView.setText(healthSaveEmptyVo.physicalExamination);
            physicalExaminationLine.setVisibility(View.VISIBLE);
        }
        //辅助检查 auxiliaryExam auxiliaryExamView auxiliaryExamLine
        if (healthSaveEmptyVo.auxiliaryExam != null && !healthSaveEmptyVo.auxiliaryExam.isBlank()){
            auxiliaryExamView.setText(healthSaveEmptyVo.auxiliaryExam);
            auxiliaryExamLine.setVisibility(View.VISIBLE);
        }

        //现存健康问题 existingHealthIssues tvCurrentHealthIssuesContext tvCurrentHealthIssuesContextLine
        if (healthSaveEmptyVo.existingHealthIssues != null && !healthSaveEmptyVo.existingHealthIssues.isBlank()){
            tvCurrentHealthIssuesContext.setText(healthSaveEmptyVo.existingHealthIssues);
            tvCurrentHealthIssuesContextLine.setVisibility(View.VISIBLE);
        }
        //更多 additionalInfo tvmore tvMoreContextLine
        if (healthSaveEmptyVo.additionalInfo != null && !healthSaveEmptyVo.additionalInfo.isBlank()){
            tvmore.setText(healthSaveEmptyVo.additionalInfo);
            tvMoreContextLine.setVisibility(View.VISIBLE);
        }




        // 设置标题和内容
        tvDialogTitle.setText("未填写内容:请检查");

        // 配置对话框
        builder.setView(dialogView);
        AlertDialog dialog = builder.create();

        // 显示对话框
        dialog.show();

        // **手动调整对话框大小**
        if (dialog.getWindow() != null) {
            dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        }

        // 监听按钮点击事件
        btnDialogCancel.setOnClickListener(v -> dialog.dismiss());

        //一般状态
        tvGeneralConditionContextEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 1; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });

        //生活方式 2 tvLifestyleContextEdit
        tvLifestyleContextEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 2; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });

        //症状 3 tvSymptomEdit
        tvSymptomEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 3; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });
        //脏器功能 4 tvOrganFunctionContextEdit
        tvOrganFunctionContextEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 4; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });
        //查体 5 physicalExaminationEdit
        physicalExaminationEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 5; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });
        //辅助检查 6 pauxiliaryExamEdit
        auxiliaryExamEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 6; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });
        //现存健康问题 7 tvCurrentHealthIssuesContextEdit
        tvCurrentHealthIssuesContextEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 7; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });
        //更多 8 tvMoreContextEdit
        tvMoreContextEdit.setOnClickListener(v -> {
            dialog.dismiss(); // 关闭对话框

            // 跳转到 "一般状况" 页面
            int targetPosition = 8; // "一般状况" Fragment 在 fragmentList 的索引
            binding.viewPager.setCurrentItem(targetPosition, true); // true 表示带动画滑动

            // 刷新 "一般状况" Fragment
//            updateHealthBaseFragment();
        });


    }

2.3 测试的数据JSON

java 复制代码
 {"cavitiesList":[],"cerebrovascularDiseaseList":["无"],"cerebrovascularDiseaseOther":"","denturesList":[],"dietPartOne":"荤素均衡","dietPartTwo":[],"dorsalPulsePartList":[],"drinkTypeList":[],"drinkTypeListOther":"","elderlySelfCareScoreEnt":{"activityId":"25","eatId":"9","toiletId":"21","washId":"13","wearId":"17"},"eyeDiseaseList":["无"],"eyeDiseaseOther":"","familyBedHistoryList":[],"heartDiseaseList":["无"],"heartDiseaseOther":"","hospitalHistoryList":[],"kidneyDiseaseList":["无"],"kidneyDiseaseOther":"","lymphNodesList":[],"lymphNodesOther":"","medicationList":[],"missingTeethList":[],"nervousSystemDiseaseOther":"","nonVaccineHistoryList":[],"otherSystemDiseaseList":["无"],"otherSystemDiseaseOther":"","ralesList":[],"ralesListOther":"","symptomList":[],"symptomOther":"","teethAlignmentList":[],"throatList":[],"vascularDiseaseList":["无"],"vascularDiseaseOther":"","visionList":[],"address":"广东省肇庆市端州区睦岗街道棠下社区居民委员会","birthday":"1955-11-16","contacts":"无","contactsNumber":"18476157184","domicileAddress":"广东省肇庆市端州区睦岗街道棠下社区居民委员会","drinkingFrequency":"从不","drunkInPastYear":"否","elderlySelfCareScore":"不能自理(≥19分)","exaTime":"2025-04-09","exerciseType":"骑车、跑步、跳舞、健身、打球","exerciseYears":"","hospitalHistoryListStatus":"无","inputPerson":"admin","jobHazards":"无","name":"欧苏虾","nervousSystemDisease":"无","nextYearExaTime":"2026-04-09","nonVaccineHistoryListStatus":"无","otherHazards":"","otherSystemDisease":"无","phoneNumber":"13534938556","quitDrinking":"否","smoking":"从不吸烟","specificJob":"","vision":""}

三、 总结

本文主要介绍了在实际安卓项目开发中,自定义弹窗的概念、应用场景以及具体的实现步骤。通过对系统默认弹窗的局限性分析,进一步阐述了为何需要自定义弹窗,以及如何根据项目需求进行灵活设计与开发。

在 Android 应用中,弹窗(Dialog)是一种非常常见的用户交互方式,常用于提示信息、警告、确认操作、输入数据等场景。Android 系统虽然为我们提供了如 AlertDialogProgressDialog 等标准弹窗组件,但这些弹窗的样式和功能相对固定,难以满足一些复杂或个性化的需求。

为了提升用户体验并实现更丰富的界面交互效果,开发者通常会选择使用自定义弹窗。所谓自定义弹窗,指的是开发者使用自己设计的 XML 布局文件和逻辑代码,替代系统默认样式,创建具有个性化风格、动画效果、复杂结构等特点的弹出窗口。这种方式不仅可以高度还原设计稿,还能更好地适配不同品牌、主题和业务场景。

相关推荐
CV资深专家2 小时前
在 Android 框架中,接口的可见性规则
android
daifgFuture6 小时前
Android 3D球形水平圆形旋转,旋转动态更换图片
android·3d
二流小码农8 小时前
鸿蒙开发:loading动画的几种实现方式
android·ios·harmonyos
爱吃西红柿!8 小时前
fastadmin fildList 动态下拉框默认选中
android·前端·javascript
悠哉清闲9 小时前
工厂模式与多态结合
android·java
大耳猫10 小时前
Android SharedFlow 详解
android·kotlin·sharedflow
火柴就是我10 小时前
升级 Android Studio 后报错 Error loading build artifacts from redirect.txt
android
androidwork12 小时前
掌握 MotionLayout:交互动画开发
android·kotlin·交互
奔跑吧 android12 小时前
【android bluetooth 协议分析 14】【HFP详解 1】【案例一: 手机侧显示来电,但车机侧没有显示来电: 讲解AT+CLCC命令】
android·hfp·aosp13·telecom·ag·hf·headsetclient
Chenyu_31012 小时前
09.MySQL内外连接
android·数据库·mysql