当前位置:首页 > 技术 > 正文内容

个人财务应用主界面头部组件实现

访客 技术 2026年8月12日 1

在列表视图中集成顶部组件,通过向ListView添加header视图来实现界面布局。

/**
 * 初始化列表头部视图组件
 */
public void initializeHeaderView() {
    View topLayout = LayoutInflater.from(this).inflate(R.layout.header_main_layout, null);
    transactionList.addHeaderView(topLayout);
    
    // 绑定头部视图中的UI元素
    expenseDisplay = topLayout.findViewById(R.id.header_expense_amount);
    incomeDisplay = topLayout.findViewById(R.id.header_income_amount);
    budgetDisplay = topLayout.findViewById(R.id.header_budget_remaining);
    dailySummary = topLayout.findViewById(R.id.header_daily_summary);
    visibilityToggle = topLayout.findViewById(R.id.header_visibility_button);

    topLayout.setOnClickListener(this);
    visibilityToggle.setOnClickListener(this);
    budgetDisplay.setOnClickListener(this);
}

为了展示头部区域的数据信息,需要从数据库查询相关统计信息。

/**
 * 查询指定日期的收支总额
 * @param targetYear 年份
 * @param targetMonth 月份  
 * @param targetDay 日期
 * @param transactionType 类型:0表示支出,1表示收入
 * @return 总金额
 */
public static double calculateDailyTotal(int targetYear, int targetMonth, int targetDay, int transactionType) {
    double amount = 0.0;

    String query = "SELECT SUM(amount) FROM financial_records WHERE year=? AND month=? AND day=? AND type=?";
    Cursor result = database.rawQuery(query, new String[]{
        String.valueOf(targetYear), 
        String.valueOf(targetMonth), 
        String.valueOf(targetDay), 
        String.valueOf(transactionType)
    });

    if (result != null && result.moveToFirst()) {
        amount = result.getDouble(result.getColumnIndexOrThrow("SUM(amount)"));
    }
    if (result != null) {
        result.close();
    }
    return amount;
}

/**
 * 查询指定月份的收支总额
 * @param targetYear 年份
 * @param targetMonth 月份
 * @param transactionType 类型:0表示支出,1表示收入
 * @return 总金额
 */
public static double calculateMonthlyTotal(int targetYear, int targetMonth, int transactionType) {
    double amount = 0.0;

    String query = "SELECT SUM(amount) FROM financial_records WHERE year=? AND month=? AND type=?";
    Cursor result = database.rawQuery(query, new String[]{
        String.valueOf(targetYear), 
        String.valueOf(targetMonth), 
        String.valueOf(transactionType)
    });

    if (result != null && result.moveToFirst()) {
        amount = result.getDouble(result.getColumnIndexOrThrow("SUM(amount)"));
    }
    if (result != null) {
        result.close();
    }
    return amount;
}

将查询到的数据填充到头部视图的各个显示组件中。

/**
 * 更新头部视图的数据展示
 */
public void updateHeaderData() {
    // 计算今日收支情况
    double todayIncome = DatabaseHelper.calculateDailyTotal(currentYear, currentMonth, currentDay, 1);
    double todayExpense = DatabaseHelper.calculateDailyTotal(currentYear, currentMonth, currentDay, 0);

    String dailyInfo = "今日支出 ¥" + todayExpense + " 收入 ¥" + todayIncome;
    dailySummary.setText(dailyInfo);

    // 计算本月收支情况
    double monthlyIncome = DatabaseHelper.calculateMonthlyTotal(currentYear, currentMonth, 1);
    double monthlyExpense = DatabaseHelper.calculateMonthlyTotal(currentYear, currentMonth, 0);
    
    incomeDisplay.setText("+" + monthlyIncome);
    expenseDisplay.setText("-" + monthlyExpense);

    // 显示预算余额
    float monthlyBudget = settings.getFloat("monthly_budget", 0.0f);
    budgetDisplay.setText(String.valueOf(monthlyBudget - monthlyExpense));
}

当用户需要调整预算设置时,需要创建专门的预算配置对话框,其构建方式与日期选择器类似。

在之前的列表头部可以看到一个可视性控制图标,用于实现数据的明文和加密显示切换功能。

private boolean isDataVisible = true;

/**
 * 切换数据显示模式:可见/隐藏
 */
public void switchDataVisibility() {
    if (isDataVisible) {
        // 启用密码遮蔽模式
        TransformationMethod maskingMethod = PasswordTransformationMethod.getInstance();
        incomeDisplay.setTransformationMethod(maskingMethod);
        expenseDisplay.setTransformationMethod(maskingMethod);
        budgetDisplay.setTransformationMethod(maskingMethod);
        visibilityToggle.setImageResource(R.drawable.icon_masked_view);
        isDataVisible = false;
    } else {
        // 恢复正常显示模式
        TransformationMethod normalMethod = HideReturnsTransformationMethod.getInstance();
        incomeDisplay.setTransformationMethod(normalMethod);
        expenseDisplay.setTransformationMethod(normalMethod);
        budgetDisplay.setTransformationMethod(normalMethod);
        visibilityToggle.setImageResource(R.drawable.icon_visible_view);
        isDataVisible = true;
    }
}
标签: Android

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。