个人财务应用主界面头部组件实现
在列表视图中集成顶部组件,通过向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;
}
}