Android Studio Java Fragment获取Context失败致RecyclerView为空
问题核心原因
你的代码有3个低级错误直接导致列表不显示、context获取异常:
onCreateView中重复inflate布局:你第一次inflate布局后找到了recyclerView实例,但最终返回给系统渲染的是第二次重新inflate的全新布局,你之前操作的recyclerView根本不在当前展示的视图树里,所有setAdapter、setLayoutManager操作全是在无效的废弃View上执行的,界面当然看不到内容。- Context获取时机错误:你在
onCreateView执行阶段就调用requireContext(),此时Fragment还没完成和Activity的附着,很容易拿到null;加上异步回调执行时如果Fragment已经被销毁,context也会为空。 - 重复初始化Adapter逻辑错误:你在Firebase返回结果的for循环里,每遍历一条数据就新建一次Adapter、重复设置LayoutManager,既冗余又会导致列表状态异常,且数据加载完成后没有正确通知Adapter刷新。
修正后的SearchFragment代码
public class SearchFragment extends Fragment implements RecyclerViewInterface { private RecyclerView recyclerView; RecyclerViewInterface rci; MyAdapter myAdapter; public List<String> nameOfFilm, youTubeUrl, photoUrl, descriptionToFilm, category; FirebaseFirestore db = FirebaseFirestore.getInstance(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 只inflate一次布局,存为根视图 View rootView = inflater.inflate(R.layout.fragment_search, container, false); // 从当前要展示的根视图上找RecyclerView recyclerView = rootView.findViewById(R.id.filmsList); rci = this; // 初始化列表集合 nameOfFilm = new ArrayList<>(); youTubeUrl = new ArrayList<>(); photoUrl = new ArrayList<>(); descriptionToFilm = new ArrayList<>(); category = new ArrayList<>(); // 提前设置LayoutManager,不需要等数据返回 recyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); // 提前初始化Adapter,先传空数据 myAdapter = new MyAdapter(requireContext(), nameOfFilm, descriptionToFilm, photoUrl, youTubeUrl, rci, category); recyclerView.setAdapter(myAdapter); loadFilmsFromDB(); // 返回同一个根视图,不要重新inflate return rootView; } private void loadFilmsFromDB() { db.collection("films").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { // 先判断Fragment是否还附着在Activity上、任务结果是否为空,避免空指针 if (!isAdded() || !task.isSuccessful() || task.getResult() == null) return; // 加载前先清空旧数据,避免重复加载时数据重复 nameOfFilm.clear(); youTubeUrl.clear(); photoUrl.clear(); descriptionToFilm.clear(); category.clear(); for (QueryDocumentSnapshot document : task.getResult()) { nameOfFilm.add(document.get("nameOfFilm").toString()); descriptionToFilm.add(document.get("descriptionToFilm").toString()); photoUrl.add(document.get("imageUrl").toString()); youTubeUrl.add(document.get("videoURL").toString()); category.add(document.get("category").toString()); } // 所有数据遍历添加完成后,一次性通知Adapter刷新,不要在循环里建Adapter myAdapter.notifyDataSetChanged(); } }); } }
其他需要修复的小问题
- 你的MyAdapter中
cardView的点击事件只创建了Intent,没有调用startActivity,后续要实现跳转功能记得补上这行逻辑。 - 异步回调里一定要先加
isAdded()判断,避免用户退出页面后回调执行,拿不到context导致崩溃。 - 不要在数据返回的循环里重复设置LayoutManager、重复创建Adapter,这类操作只需要在初始化的时候执行一次即可。
内容的提问来源于stack exchange,提问作者junior
相关产品推荐
相关产品推荐

