Firebase收入数据Fragment日期过滤功能异常求助
问题:Firebase收入数据Fragment日期过滤功能失效
我正尝试过滤展示从Firebase获取的收入数据的Fragment,数据展示没有问题,但过滤功能的实现却困难重重。当我尝试过滤时,日期选择器没有报错,但无法达到预期效果。
相关代码(ViewIncomeFragment.java)
过滤按钮点击事件
//Filter Button Button filterButton = v.findViewById(R.id.btnFilter); filterButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Filter the Income data filterIncomeByDate(startDate, endDate); // Show a dialog to get start and end date from the user Calendar calendar2 = Calendar.getInstance(); DatePickerDialog datePickerDialog2 = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { if (endDate != null) { endDate.setText(dayOfMonth + "-" + (month + 1) + "-" + year); } if(validateDates() == false){ startDate.setText("StartDate"); endDate.setText("EndDate"); } } // handle the date set event }, calendar2.get(Calendar.YEAR), calendar2.get(Calendar.MONTH), calendar2.get(Calendar.DAY_OF_MONTH)); datePickerDialog2.show(); Calendar calendar1 = Calendar.getInstance(); DatePickerDialog datePickerDialog1 = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { if (startDate != null) { startDate.setText(dayOfMonth + "-" + (month + 1) + "-" + year); } } // handle the date set event }, calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH), calendar1.get(Calendar.DAY_OF_MONTH)); datePickerDialog1.show(); } }); return v;
日期过滤方法
//Method to filter the Income by date public void filterIncomeByDate(TextView startDate, TextView endDate){ ArrayList<Income> filteredList = new ArrayList<>(); SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); try { Date start = dateFormat.parse(startDate.getText().toString()); Date end = dateFormat.parse(endDate.getText().toString()); for (Income income : incomeArrayList) { Date incomeDate = dateFormat.parse(income.getDateIncome()); if (incomeDate.after(start) && incomeDate.before(end)) { filteredList.add(income); } } } catch (ParseException e) { e.printStackTrace(); } incomeArrayList.clear(); incomeArrayList.addAll(filteredList); incomeAdapter.notifyDataSetChanged(); }
预期仅展示指定日期范围内的数据,但当前无法实现该效果。
问题原因及修复方案
1. 过滤时机完全错误
点击按钮后先执行过滤,再弹出日期选择器,此时startDate、endDate还是初始占位文本(比如"StartDate"),解析会直接抛出异常,过滤逻辑根本不执行。
修复:调整流程,在用户选择完开始、结束日期后再执行过滤,并且改为顺序选择日期(先选开始,再选结束):
filterButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 先选择开始日期 Calendar calendar1 = Calendar.getInstance(); DatePickerDialog datePickerDialog1 = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { if (startDate != null) { startDate.setText(dayOfMonth + "-" + (month + 1) + "-" + year); // 开始日期选完后,弹出结束日期选择器 Calendar calendar2 = Calendar.getInstance(); DatePickerDialog datePickerDialog2 = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year2, int month2, int dayOfMonth2) { if (endDate != null) { endDate.setText(dayOfMonth2 + "-" + (month2 + 1) + "-" + year2); // 验证日期有效后执行过滤 if(validateDates()){ filterIncomeByDate(startDate, endDate); } else { startDate.setText("StartDate"); endDate.setText("EndDate"); } } } }, calendar2.get(Calendar.YEAR), calendar2.get(Calendar.MONTH), calendar2.get(Calendar.DAY_OF_MONTH)); datePickerDialog2.show(); } } }, calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH), calendar1.get(Calendar.DAY_OF_MONTH)); datePickerDialog1.show(); } });
2. 原始数据源被覆盖,无法重复过滤
每次过滤都会清空incomeArrayList并替换为过滤后的数据,导致再次过滤时没有原始数据可筛选。
修复:初始化时保留一份原始数据源:
private ArrayList<Income> originalIncomeArrayList; // 在从Firebase获取到数据后初始化 originalIncomeArrayList = new ArrayList<>(incomeArrayList);
修改过滤方法,从原始数据中筛选:
public void filterIncomeByDate(TextView startDate, TextView endDate){ ArrayList<Income> filteredList = new ArrayList<>(); SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); try { Date start = dateFormat.parse(startDate.getText().toString()); Date end = dateFormat.parse(endDate.getText().toString()); // 从原始数据源筛选,避免覆盖原始数据 for (Income income : originalIncomeArrayList) { Date incomeDate = dateFormat.parse(income.getDateIncome()); // 调整条件,包含开始和结束当天的数据 if (!incomeDate.before(start) && !incomeDate.after(end)) { filteredList.add(income); } } } catch (ParseException e) { e.printStackTrace(); // 解析失败时恢复原始数据展示 filteredList = new ArrayList<>(originalIncomeArrayList); } incomeArrayList.clear(); incomeArrayList.addAll(filteredList); incomeAdapter.notifyDataSetChanged(); }
3. 日期范围判断排除边界
原代码incomeDate.after(start) && incomeDate.before(end)会排除开始、结束当天的数据,改成!incomeDate.before(start) && !incomeDate.after(end)即可包含边界日期。
4. 确保日期验证逻辑有效
validateDates()方法需要严格校验开始日期不晚于结束日期,避免无效的过滤范围导致无数据展示。
内容的提问来源于stack exchange,提问作者Iafiqs
相关产品推荐
相关产品推荐

