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

在ViewHolder中创建Spinner返回空值的问题排查

问题描述

我尝试在ViewHolder类中编写returnAsked方法返回Spinner,再在Activity中为这些Spinner设置适配器,以此解决在Activity外创建Spinner的问题,但这个方法返回的Spinner始终为空。


相关代码

ViewHolder中的方法

public @NonNull Spinner returnAsked(int i){
    switch (i){
        case 1:
            return avgDistance;
        case 2:
            return maxDistance;
        case 3:
            return gender;
        default:
            return gender;
    }
}

Activity中的代码

GoogleSignUpViewHolder holder= new GoogleSignUpViewHolder(recyclerView);

holder= new GoogleSignUpViewHolder(recyclerView);
btnAdd= findViewById(R.id.BtnAdd);

// Apply the adapter to the spinner
adapterGender = ArrayAdapter.createFromResource(this,
                R.array.gender_array, android.R.layout.simple_spinner_item);
adapterDistance = ArrayAdapter.createFromResource(this,
                R.array.avg_distance_array, android.R.layout.simple_spinner_item);


// Specify the layout to use when the list of choices appears

adapterGender.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapterDistance.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
if(holder.returnAsked(1)==null){
    Toast.makeText(this, " CONTEXT", Toast.LENGTH_SHORT).show();
}

holder.returnAsked(3).setAdapter(adapterGender);
holder.returnAsked(1).setAdapter(adapterDistance);
holder.returnAsked(2).setAdapter(adapterDistance);

RecyclerView适配器代码

public class GoogleSignUpAdapter extends RecyclerView.Adapter<GoogleSignUpViewHolder> {
    @NonNull
    @Override
    public GoogleSignUpViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == 0){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.birthdate_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 1){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gender_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
       else if(viewType == 2){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.avg_distance_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 3){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.avg_speed_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 4){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.picture_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 5){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.address_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 6){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.city_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 7){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.country_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 8){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.height_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 9){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.id_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 10){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.max_distance_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 11){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.max_speed_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 12){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.phone_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }
        else if(viewType == 13){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.weight_item,parent,false);
            return new GoogleSignUpViewHolder(view);
        }




        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull GoogleSignUpViewHolder holder, int position) {

    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return 14;
    }
}

问题原因
  1. 错误实例化ViewHolder:你在Activity中直接new GoogleSignUpViewHolder(recyclerView),但这个ViewHolder并没有加载对应的item布局,内部的Spinner控件完全没被初始化,自然返回null。RecyclerView的ViewHolder必须由Adapter的onCreateViewHolder方法创建,该方法会加载对应布局并完成控件初始化。
  2. ViewHolder控件范围问题:不同的ViewHolder对应不同的item布局,比如gender对应gender_item布局,avgDistance对应avg_distance_item布局,每个ViewHolder只会初始化当前布局内的Spinner,其他Spinner成员变量默认都是null。

解决方案

把Spinner的初始化和适配器设置逻辑交给Adapter处理,不要在Activity中直接操作ViewHolder。

1. 修改ViewHolder,按需初始化控件

public class GoogleSignUpViewHolder extends RecyclerView.ViewHolder {
    public Spinner gender;
    public Spinner avgDistance;
    public Spinner maxDistance;

    public GoogleSignUpViewHolder(@NonNull View itemView) {
        super(itemView);
        // 根据布局类型初始化对应Spinner
        switch (itemView.getContext().getResources().getResourceName(itemView.getId())) {
            case "com.yourpackage:id/gender_item_root": // 替换为gender_item布局根视图的id
                gender = itemView.findViewById(R.id.spinner_gender); // 替换为布局内Spinner的id
                break;
            case "com.yourpackage:id/avg_distance_item_root":
                avgDistance = itemView.findViewById(R.id.spinner_avg_distance);
                break;
            case "com.yourpackage:id/max_distance_item_root":
                maxDistance = itemView.findViewById(R.id.spinner_max_distance);
                break;
            // 其他布局的控件初始化同理
        }
    }
}

2. 修改Adapter,在绑定阶段设置适配器

public class GoogleSignUpAdapter extends RecyclerView.Adapter<GoogleSignUpViewHolder> {
    private Context mContext;
    private ArrayAdapter<String> adapterGender;
    private ArrayAdapter<String> adapterDistance;

    public GoogleSignUpAdapter(Context context) {
        mContext = context;
        // 提前初始化适配器
        adapterGender = ArrayAdapter.createFromResource(mContext,
                R.array.gender_array, android.R.layout.simple_spinner_item);
        adapterGender.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        adapterDistance = ArrayAdapter.createFromResource(mContext,
                R.array.avg_distance_array, android.R.layout.simple_spinner_item);
        adapterDistance.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    }

    @NonNull
    @Override
    public GoogleSignUpViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = null;
        switch (viewType) {
            case 0:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.birthdate_item, parent, false);
                break;
            case 1:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gender_item, parent, false);
                break;
            case 2:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.avg_distance_item, parent, false);
                break;
            case 10:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.max_distance_item, parent, false);
                break;
            // 其他case保持原逻辑
        }
        return new GoogleSignUpViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull GoogleSignUpViewHolder holder, int position) {
        // 根据位置设置对应Spinner的适配器
        switch (position) {
            case 1:
                if (holder.gender != null) {
                    holder.gender.setAdapter(adapterGender);
                }
                break;
            case 2:
                if (holder.avgDistance != null) {
                    holder.avgDistance.setAdapter(adapterDistance);
                }
                break;
            case 10:
                if (holder.maxDistance != null) {
                    holder.maxDistance.setAdapter(adapterDistance);
                }
                break;
        }
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return 14;
    }
}

3. 简化Activity代码

// 初始化RecyclerView
RecyclerView recyclerView = findViewById(R.id.your_recyclerview_id);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
GoogleSignUpAdapter adapter = new GoogleSignUpAdapter(this);
recyclerView.setAdapter(adapter);

btnAdd = findViewById(R.id.BtnAdd);

内容的提问来源于stack exchange,提问作者tavor doron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:25:28