Fragment中onActivityResult失效且Adapter无法连接的问题求助
我来帮你一步步拆解并解决这两个问题:
一、修复onActivityResult不触发&修饰符冲突问题
首先明确:Fragment的onActivityResult必须是public修饰符——因为Fragment父类中的该方法本身就是public的,重写时不能降低访问权限。你说改成protected能运行应该是个误解:大概率是宿主Activity的onActivityResult接收到了结果,而你误把Activity的逻辑当成了Fragment的。
导致Fragment的onActivityResult不触发的核心原因,通常是启动选择器时用了getActivity().startActivityForResult(...),而非直接调用Fragment自身的startActivityForResult()方法。Fragment有独立的结果回调通道,只有调用Fragment的方法,结果才会正确传递到它的onActivityResult里。
修改你的选择器启动代码:
// 把原来的getActivity().showPickerForResult(...)改成直接调用Fragment的方法 showPickerForResult(CONTACT_PICKER_REQUEST); // 或者如果需要手动构建Intent,确保用Fragment的上下文启动: Intent pickerIntent = new MultiContactPicker.Builder(getActivity()) // 你的配置参数(hideScrollbar、showTrack等)... .build(); startActivityForResult(pickerIntent, CONTACT_PICKER_REQUEST);
另外还要检查宿主Activity:如果它重写了onActivityResult,必须调用super.onActivityResult(requestCode, resultCode, data),否则会拦截结果,导致Fragment收不到回调。
二、解决"adapter is not connected"问题
这个错误本质是RecyclerView的Adapter没有提前绑定,或者数据更新逻辑不合理。优化方案如下:
- 提前初始化Adapter
不要等到onActivityResult才创建Adapter,在Fragment的视图初始化阶段就绑定空的Adapter,避免RecyclerView处于无Adapter的状态:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 初始化RecyclerView recyclerView = view.findViewById(R.id.recyclerView); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); // 提前初始化数据列表和Adapter并绑定 listItems = new ArrayList<>(); adapter = new MyRecycleAdapter(listItems, getActivity()); recyclerView.setAdapter(adapter); // FloatingActionButton的点击事件也可以移到这里(视图已完全创建) FloatingActionButton floatingActionButton = view.findViewById(R.id.picker); floatingActionButton.setOnClickListener(...); }
- 复用Adapter,更新数据后通知刷新
在onActivityResult中,不要每次都新建Adapter,而是直接往已有的listItems中添加数据,再调用Adapter的notifyDataSetChanged()触发刷新:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == CONTACT_PICKER_REQUEST){ if(resultCode == RESULT_OK) { List<ContactResult> results = MultiContactPicker.obtainResult(data); for (ContactResult result : results) { ListItem listItem = new ListItem( "Name: "+result.getDisplayName(), "Contact No: "+result.getPhoneNumbers() ); listItems.add(listItem); } // 通知Adapter数据已更新,无需重新创建 adapter.notifyDataSetChanged(); Toast.makeText(getActivity(), "MyTag"+results.get(0).getDisplayName(), Toast.LENGTH_SHORT).show(); Log.d("MyTag", results.get(0).getDisplayName()); } else if(resultCode == RESULT_CANCELED){ System.out.println("User closed the picker without selecting items."); } } }
额外建议
如果你的项目使用AndroidX,推荐改用registerForActivityResultAPI替代旧的startActivityForResult体系——这是官方推荐的现代方案,能彻底避免Fragment与Activity之间的结果传递冲突,代码也更简洁。
内容的提问来源于stack exchange,提问作者Vector Arora




