自定义片段的首选项

时间:2017-08-03 15:56:15

标签: android android-fragments android-dialogfragment

我目前正在xml文件中构建PreferenceScreen。其中一个子元素,更准确地说是Preference元素,有一个名为android:setFragment的属性,其描述如下:

  

设置单击此首选项时要显示的片段的类名。

所以我在首选项xml文件中添加了自定义片段:

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">
    <Preference
        android:title = "test"
        android:fragment="com.test.bla.SomeTestFragment"/>
</PreferenceScreen>

这是我定义自定义片段(实际扩展DialogFragment)的方式:

public class SomeTestFragment extends DialogFragment 
{
    public static final String FRAGMENT_TAG = SomeTestFragment.class.getName();

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        Dialog dialog = new Dialog(getContext());
        dialog.setTitle("Delete User");

        FragmentDeleteUserBinding binding = FragmentDeleteUserBinding.inflate(LayoutInflater.from(getContext()));
        binding.setFragment(this);

        dialog.setContentView(binding.getRoot());
        return dialog;
    }

    public void onClickDeleteCredential()
    {
       DeleteCredentialFragment.deleteCredential(getChildFragmentManager());
    }


    public void onClickClose()
    {
        dismiss();
    }
}

但是当我点击该偏好时没有任何反应,自定义片段没有显示。我在这里想念一下吗?

有人可能会问为什么我强制我的自定义DialogFragment。这只是因为我可以访问getChildFragmentManager方法,如果我的自定义片段从DialogPreference延伸,我就无法实现相同的目标。

2 个答案:

答案 0 :(得分:1)

这不明确,但我认为片段必须是PreferenceFragment。

  

使用android:fragment属性,每个头都声明一个实例   PreferenceFragment应在用户选择时打开   报头中。

https://developer.android.com/guide/topics/ui/settings.html

但是,您可以在PreferenceActivity或主PreferenceFragment中执行操作,在该首选项上设置onClickListener,然后在将片段添加到backstack后使用FragmentManager显示该片段:

class SettingsFragment: PreferenceFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

            // Set click listener for directory picker
            findPreference("addKeyboard").setOnPreferenceClickListener( {
                preference ->

                try {
                    // Display the fragment as the main content.
                      fragmentManager.beginTransaction()
                            .replace(android.R.id.content, ManageKeyboardsFragment())
                            .addToBackStack(null)
                            .commit()
                    true

                } catch (e: Exception) {
                    displayError("could not open managekeyboards fragment", e)
                    true
                }
            })
    }
}

答案 1 :(得分:0)

好像您在fragment属性中提供的字符串只是一条要发送到您的父级活动的消息。您的家长活动负责实例化正确的Fragment,并执行仪式来呈现它。

platform docs似乎表示这样:

  

当用户点击带有关联片段的首选项时,将调用接口方法PreferenceFragmentCompat.OnPreferenceStartFragmentCallback.onPreferenceStartFragment()

onPreferenceStartFragment的参数似乎是单击的首选项和承载它的PreferenceFragmentCompat。

该页面上有一个代码示例,其中onPreferenceStartFragment的实现将返回值pref.getFragment()传递到getSupportFragmentManager().getFragmentFactory().instantiate中。

这时,我正在使用Xamarin,无论出于什么原因,getFragmentFactory都没有等效的API。但是,遗憾的是,fragment属性不是魔术;您的Activity必须承担繁重的任务。

这是一个related answer,在这里我用C#/ Xamarin编写了一个更完整的工作示例。