You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Fragment中onActivityResult失效且Adapter无法连接的问题求助

解决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没有提前绑定,或者数据更新逻辑不合理。优化方案如下:

  1. 提前初始化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(...);
}
  1. 复用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

火山引擎 最新活动