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

setTargetFragment已废弃时如何正确使用PreferenceDialogFragmentCompat

问题根本原因

你反编译得到的校验逻辑完全正确,截至androidx.preference:1.2.0版本,PreferenceDialogFragmentCompat仍然硬编码要求目标Fragment必须实现TargetFragment接口(该接口已经由PreferenceFragmentCompat默认实现),且内部逻辑依赖getTargetFragment()获取关联的Preference实例,你移除setTargetFragment()调用后校验直接失败抛出异常。
另外你误用了replace事务加载DialogFragment,DialogFragment本身是弹窗容器,应该调用自带的show()方法展示,不需要替换布局容器。

可选解决方案

方案1:临时保留setTargetFragment(短期兼容首选)

setTargetFragment只是被标记为废弃,官方不会在现有稳定版系统/依赖库中直接移除该API,且PreferenceDialogFragmentCompat本身的内部逻辑仍依赖该API,因此你可以暂时保留原有调用,等待官方preference库后续版本适配Fragment Result API后再做修改,不会影响现有应用的正常运行。

方案2:自定义DialogFragment适配Fragment Result API(长期合规方案)

重写你的自定义PreferenceDialogFragmentCompat子类,跳过原有target校验逻辑,改用Fragment Result API传递选择结果,具体实现如下:

  1. 改造自定义DialogFragment:
public class NumberPickerPreferenceDialogFragment extends PreferenceDialogFragmentCompat {
    public static NumberPickerPreferenceDialogFragment newInstance(String key) {
        NumberPickerPreferenceDialogFragment fragment = new NumberPickerPreferenceDialogFragment();
        Bundle args = new Bundle();
        args.putString(ARG_KEY, key);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // 跳过父类的targetFragment校验逻辑,自己处理结果返回
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onDialogClosed(boolean positiveResult) {
        if (positiveResult) {
            int selectedValue = 你选择的数值;
            Bundle result = new Bundle();
            result.putInt("selected_value", selectedValue);
            // 把结果返回给宿主Fragment
            getParentFragmentManager().setFragmentResult("number_picker_result", result);
        }
    }
}
  1. 修改PreferenceFragmentCompat中的调用逻辑:
@Override
public void onDisplayPreferenceDialog(Preference preference) {
    if (getParentFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
        return;
    }

    final DialogFragment f;
    if (preference instanceof NumberPickerPreference) {
        f = NumberPickerPreferenceDialogFragment.newInstance(preference.getKey());
        // 注册结果监听接收选择值
        getParentFragmentManager().setFragmentResultListener("number_picker_result", this, (requestKey, result) -> {
            int selectedValue = result.getInt("selected_value");
            // 同步更新Preference的存储值和展示状态
            SharedPreferences.Editor editor = preference.getSharedPreferences().edit();
            editor.putInt(preference.getKey(), selectedValue);
            editor.apply();
            preference.setSummary(String.valueOf(selectedValue));
        });
    } else if (preference instanceof TextAutoCompletePreference) {
        // 按照相同逻辑改造TextAutoCompletePreferenceDialogFragment即可
        f = TextAutoCompletePreferenceDialogFragment.newInstance(preference.getKey());
    } else {
        f = null;
    }

    if (f != null) {
        // 直接调用show方法展示弹窗,不需要调用setTargetFragment
        f.show(getParentFragmentManager(), DIALOG_FRAGMENT_TAG);
    } else {
        super.onDisplayPreferenceDialog(preference);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 11:18:03