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

Android自定义Spinner加载数据源点击下拉崩溃问题求助

解决Spinner自定义布局后下拉崩溃的问题

嘿,我来帮你搞定这个Spinner点击下拉就崩溃的问题!咱们先拆解问题根源,再一步步解决。

问题原因分析

从你的崩溃日志和代码来看,核心问题出在Spinner的双视图机制和ArrayAdapter的使用方式上:

  • Spinner有两个核心视图方法:getView()负责显示当前选中的项,getDropDownView()负责显示下拉展开后的每一项
  • 你在HCPListAdapter的构造器里传入的第二个参数是0:super(context, 0, users);
  • 你只重写了getView()来加载自定义布局,但getDropDownView()沿用了ArrayAdapter的默认实现——它会尝试用构造器里的0作为布局ID去加载视图,这显然找不到有效资源,所以抛出了Resources$NotFoundException(Resource ID #0x0找不到)

解决方案

这里有两种靠谱的解决方式,你可以根据需求选择:

方案一:重写getDropDownView()方法(推荐,更灵活)

这种方式适合后续可能需要区分「选中项布局」和「下拉项布局」的场景,直接在HCPListAdapter中添加getDropDownView()的实现,逻辑和getView()保持一致即可:

public class HCPListAdapter extends ArrayAdapter<User> {
    public HCPListAdapter(Context context, List<User> users){
        super(context, 0, users);
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        // 原有getView逻辑不变
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.hcp_dropdown, parent, false);
        }
        HCPViewHolder viewHolder = (HCPViewHolder) convertView.getTag();
        if (viewHolder == null) {
            viewHolder = new HCPViewHolder();
            viewHolder.name = convertView.findViewById(R.id.Row_assessment_file_for_list_assessment_text_name);
            convertView.setTag(viewHolder);
        }
        User user = getItem(position);
        if (user != null) {
            viewHolder.name.setText(user.getTitle() + ". " + user.getLastname() + ", " + user.getFirstname());
        } else {
            viewHolder.name.setText(R.string.error_unknown);
        }
        return convertView;
    }

    // 新增getDropDownView方法
    @NonNull
    @Override
    public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.hcp_dropdown, parent, false);
        }
        HCPViewHolder viewHolder = (HCPViewHolder) convertView.getTag();
        if (viewHolder == null) {
            viewHolder = new HCPViewHolder();
            viewHolder.name = convertView.findViewById(R.id.Row_assessment_file_for_list_assessment_text_name);
            convertView.setTag(viewHolder);
        }
        User user = getItem(position);
        if (user != null) {
            viewHolder.name.setText(user.getTitle() + ". " + user.getLastname() + ", " + user.getFirstname());
        } else {
            viewHolder.name.setText(R.string.error_unknown);
        }
        return convertView;
    }

    private class HCPViewHolder{
        public TextView name;
    }
}

方案二:修改ArrayAdapter构造器参数(适合布局完全一致的场景)

如果你的选中项和下拉项布局完全相同,可直接修改构造器,将第二个参数从0改为自定义布局IDR.layout.hcp_dropdown,这样ArrayAdapter的默认实现会自动用该布局加载下拉视图:

public class HCPListAdapter extends ArrayAdapter<User> {
    // 修改构造器的第二个参数
    public HCPListAdapter(Context context, List<User> users){
        super(context, R.layout.hcp_dropdown, users);
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        // 原有getView逻辑不变
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.hcp_dropdown, parent, false);
        }
        HCPViewHolder viewHolder = (HCPViewHolder) convertView.getTag();
        if (viewHolder == null) {
            viewHolder = new HCPViewHolder();
            viewHolder.name = convertView.findViewById(R.id.Row_assessment_file_for_list_assessment_text_name);
            convertView.setTag(viewHolder);
        }
        User user = getItem(position);
        if (user != null) {
            viewHolder.name.setText(user.getTitle() + ". " + user.getLastname() + ", " + user.getFirstname());
        } else {
            viewHolder.name.setText(R.string.error_unknown);
        }
        return convertView;
    }

    private class HCPViewHolder{
        public TextView name;
    }
}

额外提示

如果后续你想让选中项显示简洁信息(比如仅姓名),下拉项展示邮箱等额外内容,只需在getView()和getDropDownView()中分别加载不同布局,或在同一布局里控制控件的显示隐藏即可。

内容的提问来源于stack exchange,提问作者Mwikala Kangwa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:56:13