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

如何在ArrayList中声明View的ID?多ID场景实现遇崩溃问题

问题分析与解决方案

你的代码直接崩溃是因为**progressBar变量从未初始化**,往列表里添加的全是null对象,调用progressBarList.get(0)时必然触发NullPointerException。而且就算初始化了,当前写法也没把找到的ProgressBar实例存入列表,完全没实现批量管理的目的。

下面给你两种可行的批量管理ProgressBar的方案:

方案一:利用ViewBinding反射批量获取(推荐)

如果你的布局里ProgressBar的ID是有规律的(比如id_1、id_2...id_100),可以通过反射直接从Binding对象中获取对应的View,不用手动逐个findViewById:

public class MiddleScreenFragment extends Fragment {
    private FragmentMiddleScreenfragmentBinding binding;
    List<ProgressBar> progressBarList = new ArrayList<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentMiddleScreenfragmentBinding.inflate(inflater, container, false);
        View view = binding.getRoot();

        // 假设ID是id_1到id_100,循环批量获取
        for (int i = 1; i <= 100; i++) {
            try {
                // 通过反射拿到Binding类中对应的字段
                Field field = FragmentMiddleScreenfragmentBinding.class.getField("id_" + i);
                ProgressBar pb = (ProgressBar) field.get(binding);
                if (pb != null) {
                    progressBarList.add(pb);
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                // 遇到不存在的ID时跳过,避免崩溃
                e.printStackTrace();
            }
        }

        // 使用示例:给第一个进度条设置进度
        if (!progressBarList.isEmpty()) {
            progressBarList.get(0).setProgress(50);
        }

        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null; // 销毁时置空Binding,避免内存泄漏
    }
}

方案二:通过资源数组批量查找(无需反射)

如果不想用反射,可以先在资源文件中定义所有ProgressBar的ID数组,再批量查找:

  1. 在res/values/arrays.xml中添加ID数组:
<array name="progress_bar_ids">
    <item>@id/id_1</item>
    <item>@id/id_2</item>
    <!-- 把所有需要管理的ProgressBar ID都列在这里 -->
</array>
  1. 在Fragment中读取数组并批量获取View:
public class MiddleScreenFragment extends Fragment {
    private FragmentMiddleScreenfragmentBinding binding;
    List<ProgressBar> progressBarList = new ArrayList<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentMiddleScreenfragmentBinding.inflate(inflater, container, false);
        View view = binding.getRoot();

        // 从资源文件中获取ID数组
        int[] pbIds = getResources().getIntArray(R.array.progress_bar_ids);
        for (int id : pbIds) {
            ProgressBar pb = view.findViewById(id);
            if (pb != null) {
                progressBarList.add(pb);
            }
        }

        // 使用示例
        if (!progressBarList.isEmpty()) {
            progressBarList.get(0).setProgress(50);
        }

        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}

额外注意事项

  • 类名规范:Java类名首字母需大写,你的middleScreenfragment应改为MiddleScreenFragment,符合开发规范。
  • 空判断:批量获取View时一定要检查是否为null,避免因ID拼写错误或布局修改导致崩溃。
  • 内存泄漏:Fragment销毁时必须将Binding置为null,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Cristian Nascimento

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:06:42