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

Android实现Spinner选中项联动RecyclerView加载对应分类数据

问题核心错误点
  • 循环逻辑错误:onItemSelected回调内构造列表的for循环写为for(int j=0;j<50;i++),循环自增的是外层回调参数i而非循环变量j,会直接触发死循环
  • 刷新逻辑缺失:仅在回调中创建了新的Adapter实例,但没有将新实例绑定到RecyclerView,也没有触发数据集刷新通知,列表无法感知数据变化
  • 细节错误:Toast仅创建实例未调用show()方法,无法弹出提示;Spinner绑定的默认planets_array数据源和需求的4个分类不匹配
修复方案

前置配置

首先在res/values/arrays.xml中定义Spinner需要的4个分类选项:

<resources>
    <string-array name="category_array">
        <item>Men</item>
        <item>Women</item>
        <item>Kids</item>
        <item>Cars</item>
    </string-array>
</resources>

Adapter改造

给RecyclerView的Adapter新增数据集更新方法,复用同一个Adapter实例减少性能损耗:

public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
    private ArrayList<ExampleItem> mExampleList;

    public ExampleAdapter(ArrayList<ExampleItem> exampleList) {
        mExampleList = exampleList;
    }

    // 新增数据更新方法
    public void setData(ArrayList<ExampleItem> newList) {
        mExampleList.clear();
        mExampleList.addAll(newList);
        notifyDataSetChanged();
    }

    // 下方保留你原有的ViewHolder、onCreateViewHolder、onBindViewHolder、getItemCount逻辑即可
    public static class ExampleViewHolder extends RecyclerView.ViewHolder {
        // 你的item控件声明与绑定
        public ExampleViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }

    @NonNull
    @Override
    public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item, parent, false);
        return new ExampleViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull ExampleViewHolder holder, int position) {
        ExampleItem currentItem = mExampleList.get(position);
        // 你的控件赋值逻辑
    }

    @Override
    public int getItemCount() {
        return mExampleList.size();
    }
}

如果不想修改Adapter代码,每次切换分类时创建新Adapter实例后调用mRecyclerView.setAdapter(mAdapter)也能实现刷新,但频繁创建Adapter实例性能较差,不推荐。

修复后的MainActivity代码

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
    private RecyclerView mRecyclerView;
    private ExampleAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化Spinner
        Spinner spinner = findViewById(R.id.spinner);
        ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(this,
                R.array.category_array, android.R.layout.simple_spinner_item);
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(spinnerAdapter);
        spinner.setOnItemSelectedListener(this);

        // 初始化RecyclerView
        mRecyclerView = findViewById(R.id.recyclerView);
        mRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(this);
        mAdapter = new ExampleAdapter(new ArrayList<>());
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);

        // 默认加载第一个分类(Men)的数据,和Spinner默认选中项对齐
        updateListByCategory(0);
    }

    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
        String selectedCategory = adapterView.getItemAtPosition(position).toString();
        Toast.makeText(this, selectedCategory, Toast.LENGTH_SHORT).show();
        updateListByCategory(position);
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {}

    /**
     * 根据Spinner选中位置加载对应分类数据
     * @param categoryPos 0:Men 1:Women 2:Kids 3:Cars
     */
    private void updateListByCategory(int categoryPos) {
        ArrayList<ExampleItem> targetList = new ArrayList<>();
        switch (categoryPos) {
            case 0:
                // 替换为男性姓名真实数据
                String[] menNames = {"John", "Mike", "Tom", "Jack", "David"};
                for (int i = 0; i < menNames.length; i++) {
                    targetList.add(new ExampleItem(menNames[i], "男性用户" + (i+1)));
                }
                break;
            case 1:
                // 替换为女性姓名真实数据
                String[] womenNames = {"Lily", "Lucy", "Amy", "Emma", "Olivia"};
                for (int i = 0; i < womenNames.length; i++) {
                    targetList.add(new ExampleItem(womenNames[i], "女性用户" + (i+1)));
                }
                break;
            case 2:
                // 替换为儿童姓名真实数据
                String[] kidNames = {"Tim", "Bob", "Alice", "Zoe", "Max"};
                for (int i = 0; i < kidNames.length; i++) {
                    targetList.add(new ExampleItem(kidNames[i], "儿童用户" + (i+1)));
                }
                break;
            case 3:
                // 替换为车辆名称真实数据
                String[] carNames = {"Tesla Model 3", "BYD Han", "BMW 3", "Benz C", "Audi A4"};
                for (int i = 0; i < carNames.length; i++) {
                    targetList.add(new ExampleItem(carNames[i], "车型" + (i+1)));
                }
                break;
        }
        mAdapter.setData(targetList);
    }
}
注意事项
  • 布局文件activity_main中需要同时存在id为spinner的Spinner控件、id为recyclerView的RecyclerView控件,否则会触发空指针异常
  • 示例中的分类测试数据可以替换为你自己的业务数据
  • 声明Adapter变量时尽量使用具体类型而非基类RecyclerView.Adapter,否则无法调用自定义的setData方法

内容的提问来源于stack exchange,提问作者Kazanaki HD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:39:26