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

自定义BaseAdapter复用视图出现脏视图问题,求简洁优化方案

解决BaseAdapter视图复用导致的显示异常问题

问题根源

你的代码仅在满足rideId=-1等条件时修改控件状态,但视图复用后,之前被修改过的控件状态会被保留,被其他列表项(比如第一个元素)复用,从而出现不符合预期的显示效果。

简洁解决方案

不需要自行维护视图列表,核心思路是在getView方法中先重置所有控件的默认状态,再根据当前列表项的条件做特殊修改。这样无论视图是否被复用,都会先恢复到初始状态,再适配当前列表项的需求,既保留视图复用的性能优势,又能避免状态混乱。

改造后的示例代码

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // 保留视图复用逻辑,这是滚动流畅性的关键
    if(convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false);
    }

    // 获取当前列表项对应的数据源
    EmployeeData employeeData = getItem(position);

    // 先获取所有需要操作的控件
    TextView name = convertView.findViewById(R.id.name);
    TextView arrived = convertView.findViewById(R.id.arrived);
    TextView otp = convertView.findViewById(R.id.otp);
    View gender = convertView.findViewById(R.id.gender);
    TextView pickDropTime = convertView.findViewById(R.id.pickDropTime);
    View call = convertView.findViewById(R.id.call);

    // 1. 重置所有控件到默认状态(与布局初始状态或非特殊列表项的预期状态一致)
    name.setText(employeeData.getName());
    arrived.setText(employeeData.getArrivedText());
    arrived.setBackgroundTintList(context.getResources().getColorStateList(R.color.default_arrived_bg));
    otp.setText(employeeData.getOtp());
    otp.setBackgroundTintList(context.getResources().getColorStateList(R.color.default_otp_bg));
    gender.setVisibility(View.VISIBLE);
    pickDropTime.setText(employeeData.getPickDropTime());
    call.setVisibility(View.VISIBLE);

    // 2. 针对特殊条件修改控件状态
    if(employeeData.getRideId().equals("-1") && position != 0 && cabDetails.getRideType().equals("0")) {
        name.setText("Office");
        arrived.setText("");
        arrived.setBackgroundTintList(context.getResources().getColorStateList(R.color.colorWhite));
        otp.setText("");
        otp.setBackgroundTintList(context.getResources().getColorStateList(R.color.colorWhite));
        gender.setVisibility(View.INVISIBLE);
        pickDropTime.setText(new DateTime().Convert24To12Format(cabDetails.getLoginLogoutDateTime().split(" ")[1]));
        call.setVisibility(View.INVISIBLE);
    }

    return convertView;
}

额外性能优化:ViewHolder模式

为避免每次getView都重复调用findViewById,可以用ViewHolder缓存控件引用,进一步提升滚动流畅度:

// 定义ViewHolder类缓存控件引用
static class ViewHolder {
    TextView name;
    TextView arrived;
    TextView otp;
    View gender;
    TextView pickDropTime;
    View call;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false);
        holder = new ViewHolder();
        holder.name = convertView.findViewById(R.id.name);
        holder.arrived = convertView.findViewById(R.id.arrived);
        holder.otp = convertView.findViewById(R.id.otp);
        holder.gender = convertView.findViewById(R.id.gender);
        holder.pickDropTime = convertView.findViewById(R.id.pickDropTime);
        holder.call = convertView.findViewById(R.id.call);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    EmployeeData employeeData = getItem(position);

    // 重置默认状态
    holder.name.setText(employeeData.getName());
    holder.arrived.setText(employeeData.getArrivedText());
    holder.arrived.setBackgroundTintList(context.getResources().getColorStateList(R.color.default_arrived_bg));
    holder.otp.setText(employeeData.getOtp());
    holder.otp.setBackgroundTintList(context.getResources().getColorStateList(R.color.default_otp_bg));
    holder.gender.setVisibility(View.VISIBLE);
    holder.pickDropTime.setText(employeeData.getPickDropTime());
    holder.call.setVisibility(View.VISIBLE);

    // 特殊条件处理
    if(employeeData.getRideId().equals("-1") && position != 0 && cabDetails.getRideType().equals("0")) {
        holder.name.setText("Office");
        holder.arrived.setText("");
        holder.arrived.setBackgroundTintList(context.getResources().getColorStateList(R.color.colorWhite));
        holder.otp.setText("");
        holder.otp.setBackgroundTintList(context.getResources().getColorStateList(R.color.colorWhite));
        holder.gender.setVisibility(View.INVISIBLE);
        holder.pickDropTime.setText(new DateTime().Convert24To12Format(cabDetails.getLoginLogoutDateTime().split(" ")[1]));
        holder.call.setVisibility(View.INVISIBLE);
    }

    return convertView;
}

内容的提问来源于stack exchange,提问作者Prajjwal Srivastav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:43:19