You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中ListView产品过期日期与当前日期对比问题求助

问题分析与解决方案

Let's troubleshoot this issue step by step. Here are the key problems in your current code and how to fix them:

1. 空异常捕获导致调试无门

你的catch (Exception e)块是空的,这意味着如果日期解析失败(比如存储的日期格式和dd-MM-yyyy不匹配),你完全看不到任何错误提示,根本没法定位问题。这大概率是代码没生效的核心原因之一。

修复方式:在catch块中添加异常日志和提示:

catch (Exception e){
    e.printStackTrace(); // 打印错误到Logcat,方便排查
    Toast.makeText(activity, "日期解析出错:" + e.getMessage(), Toast.LENGTH_LONG).show();
}

2. 日期解析未指定Locale

SimpleDateFormat依赖系统Locale,如果你的设备地区设置不兼容dd-MM-yyyy格式,解析会直接失败。

修复方式:创建格式化器时明确指定Locale:

SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.getDefault());
// 也可以固定用Locale.ENGLISH,避免不同地区的格式差异

3. Toast重复弹出的体验问题

getView()方法会在ListView滚动、视图复用的时候多次调用,这会导致每一次复用过期产品的视图都弹出Toast,体验非常糟糕。建议改为对过期产品做UI标记(比如改文字颜色、添加过期标签),而非弹Toast。

示例修改:

if ((Date1.compareTo(Date2)) > 0){
    // 标记过期:把日期改成红色并添加过期标识
    holder.productDate.setTextColor(Color.RED);
    holder.productDate.setText(product.get(ListViewActivity.KEY_DATE) + " (已过期)");
} else {
    // 重置状态,避免复用视图时残留之前的红色样式
    holder.productDate.setTextColor(Color.BLACK);
    holder.productDate.setText(product.get(ListViewActivity.KEY_DATE));
}

4. 确保日期格式完全匹配

确认你存储的KEY_DATE对应的字符串严格是dd-MM-yyyy格式(比如05-10-2024,而非5-10-2024或05/10/2024),格式不匹配会直接导致parse()失败。


修正后的完整getView()方法

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ListProductViewHolder holder = null;
    if(convertView == null){
        holder = new ListProductViewHolder();
        convertView = LayoutInflater.from(activity).inflate(R.layout.list_row, parent, false);
        holder.productName = convertView.findViewById(R.id.title);
        holder.productDescription = convertView.findViewById(R.id.description);
        holder.productDate = convertView.findViewById(R.id.duration);
        convertView.setTag(holder);
    }else{
        holder = (ListProductViewHolder) convertView.getTag();
    }

    HashMap<String, String> product = data.get(position);
    try {
        holder.productName.setText(product.get(ListViewActivity.KEY_PRODUCT_NAME));
        holder.productDescription.setText(product.get(ListViewActivity.KEY_DESCRIPTION));
        
        String currentDate = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date());
        String pdate = product.get(ListViewActivity.KEY_DATE);
        String pattern = "dd-MM-yyyy";
        SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.getDefault());
        
        Date currentDateObj = formatter.parse(currentDate);
        Date productDateObj = formatter.parse(pdate);

        // 先重置日期的样式,避免视图复用残留状态
        holder.productDate.setTextColor(Color.BLACK);
        if (currentDateObj.compareTo(productDateObj) > 0){
            // 产品已过期,执行你的逻辑
            holder.productDate.setText(pdate + " (已过期)");
            holder.productDate.setTextColor(Color.RED);
        } else {
            holder.productDate.setText(pdate);
        }
    }catch (Exception e){
        e.printStackTrace();
        Toast.makeText(activity, "处理产品数据出错:" + e.getMessage(), Toast.LENGTH_SHORT).show();
    }
    return convertView;
}

额外优化建议

  • 避免在getView()中频繁创建SimpleDateFormat对象,把它定义为Adapter的静态成员变量,提升性能:
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault());
  • 如果你的项目支持Java 8+,建议使用更安全易用的LocalDate API替代Date和SimpleDateFormat:
// 示例:用LocalDate对比日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy", Locale.getDefault());
LocalDate currentLocalDate = LocalDate.now();
LocalDate productLocalDate = LocalDate.parse(pdate, formatter);

if (currentLocalDate.isAfter(productLocalDate)) {
    // 产品已过期
}

内容的提问来源于stack exchange,提问作者St Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:15:47