Android Fragment加载API数据时无法定位目标布局问题求助
问题原因分析
- 你当前使用的是单Activity + 多Fragment的官方导航架构,所有业务页面的视图都隶属于各个独立Fragment,你要找的
R.id.rv_jokes_top10控件大概率写在某个Fragment的布局文件中,并不属于MainActivity的根布局 - Activity的
onCreate生命周期阶段,NavHost里的Fragment还未完成视图挂载,此时在Activity中调用findViewById找Fragment里的控件必然返回空值,后续调用布局管理器设置方法会直接触发空指针崩溃,自然无法绑定API数据到目标布局
修复方案
- 将列表相关逻辑迁移到对应Fragment
把RecyclerView初始化、Adapter配置、API请求的逻辑全部转移到你要展示笑话列表的目标Fragment中,放在Fragment的onViewCreated方法中执行,此时Fragment的视图已经完成初始化,可以正常获取到控件实例,示例代码如下:
// 示例:展示笑话列表的Fragment内的逻辑 public class HomeFragment extends Fragment implements JokesAPITask.JokeListener{ private FragmentHomeBinding binding; private JokesAdapter jokesAdapter; private ArrayList<Joke> jokesList = new ArrayList<>(); @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentHomeBinding.inflate(inflater, container, false); return binding.getRoot(); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 初始化列表 LinearLayoutManager layoutManager = new LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false); binding.rvJokesTop10.setLayoutManager(layoutManager); jokesAdapter = new JokesAdapter(jokesList); binding.rvJokesTop10.setAdapter(jokesAdapter); // 发起API请求 String[] params = {"https://official-joke-api.appspot.com/random_ten"}; new JokesAPITask(this).execute(params); } @Override public void onJokesAvailable(List<Joke> jokes) { jokesList.clear(); jokesList.addAll(jokes); jokesAdapter.notifyDataSetChanged(); } @Override public void onDestroyView() { super.onDestroyView(); binding = null; } }
- 移除MainActivity中冗余的列表逻辑
删掉MainActivity里RecyclerView初始化、API请求相关的代码,保持MainActivity只负责导航抽屉、顶部ActionBar等全局框架逻辑即可,符合单Activity架构的职责划分。 - 如果你确实需要Activity触发数据加载再同步到Fragment,可以使用Jetpack ViewModel实现数据共享,Activity请求完数据存入ViewModel,Fragment观察ViewModel的数据变化自动更新列表,避免跨视图树直接访问控件的问题。
内容的提问来源于stack exchange,提问作者WigginsFroome
相关产品推荐
相关产品推荐

