🐳 《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 布局文件和逻辑代码,替代系统默认样式,创建具有个性化风格、动画效果、复杂结构等特点的弹出窗口。这种方式不仅可以高度还原设计稿,还能更好地适配不同品牌、主题和业务场景。

相关推荐
_小马快跑_5 小时前
Android | 利用ItemDecoration绘制RecyclerView分割线
android
_小马快跑_5 小时前
别再手写 if/else 判断了!赶紧来掌握 Kotlin 的 coerce 三兄弟吧
android
_小马快跑_5 小时前
Android Xfermode应用:实现圆角矩形、圆形等图片裁切
android
怀旧,6 小时前
【数据结构】4.单链表实现通讯录
android·服务器·数据结构
yechaoa6 小时前
Widget开发实践指南
android·前端
顾林海8 小时前
Flutter 图标和按钮组件
android·开发语言·前端·flutter·面试
匹马夕阳9 小时前
(二十二)安卓开发中的数据存储之SQLite简单使用
android·数据库·sqlite
_一条咸鱼_9 小时前
大厂Android面试秘籍:上下文管理模块
android·面试·android jetpack
mingzhi619 小时前
绿盟二面面试题
android·web安全·渗透测试
SY.ZHOU11 小时前
Flutter 与原生通信
android·flutter·ios