如何在首选项标头中使用 PreferenceFragmentCompat [英] How to use PreferenceFragmentCompat in the preference header

查看:28
本文介绍了如何在首选项标头中使用 PreferenceFragmentCompat的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习在 Xamarin Android 应用程序中构建首选项页面的方法.我找到了很多带有 PreferenceFragment 的示例,但它被标记为已弃用,我很难在当前阶段重写它们.

I'm trying to learn ways to build preference pages in the Xamarin Android application. I found a lot of examples with PreferenceFragment but it was marked as deprecated and it is difficult for me to rewrite them on the current stage.

我创建了活动来表示标题.我添加了 IntentFilter 以便我可以从设置菜单中的应用程序列表访问此活动.它还有内部类来将一些偏好组合在一起:

I've created activity to represent headers. I added IntentFilter so I can access this activity from apps list in the settings menu. Also it has internal class to group some preferences together:

namespace droid.examples.Preferences
{
    [Activity(Label = "Settings activity", Theme = "@style/AppTheme", Name = "droid.examples.Preferences.SettingsActivity")]
    [IntentFilter(new string[] { "android.intent.action.APPLICATION_PREFERENCES" })]
    public class SettingsActivity : PreferenceActivity
    {
        public override void OnBuildHeaders(IList<Header> target)
        {
            base.OnBuildHeaders(target);
            LoadHeadersFromResource(Resource.Xml.preference_headers, target);
        }

        public class SettingsFragment : PreferenceFragmentCompat
        {
            public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
            {
                // Load the Preferences from the XML file
                SetPreferencesFromResource(Resource.Xml.app_preferences, rootKey);
            }
        }
    }
}

我无法通过从preference_headers.xml 中选择Prefs 1"标题打开我的app_preferences.xml:

My app_preferences.xml which I can't open by selecting "Prefs 1" header from preference_headers.xml:

<?xml version="1.0" encoding="utf-8" ?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  <PreferenceCategory android:title="Category">
    <CheckBoxPreference
            android:key="checkbox_preference"
            android:title="Developer mode"
            android:summary="Allow user to see detailed messages" />
  </PreferenceCategory>
</PreferenceScreen>

我有preference_headers.xml.当我单击应用程序名称附近的齿轮时,它会打开.它看起来像这样:

I have preference_headers.xml. It opens when I click on gear wheel near application name. It looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
  <header android:fragment="droid.examples.Preferences.SettingsActivity.SettingsFragment"
          android:title="Prefs 1"
          android:summary="An example of some preferences." />
</preference-headers>

我的包名:droid.examples

My package name: droid.examples

我认为一个问题与 android:fragment 属性值有关.建立该价值的规则是什么?

I think that one problem related to the android:fragment attribute value. What is the rules to build that value?

我想它必须从包名"开始.它应该在类名和包名之间包含命名空间吗?

I suppose that it must start from 'package name'. Should it contain namespace between class name and package name?

属性值中的$是什么意思?是用来标记内部类的吗?我在几个地方看到下一段代码:

What does $ mean in the attribute value? Is it used to mark internal class? I saw in the several places next code:

android:fragment="com.example.android.apis.preference.PreferenceWithHeaders$Prefs1Fragment"

我希望你能帮我找出我犯错的地方.

I hope you can help me find where I made a mistakes.

来自 GitHub 的源代码

推荐答案

我花了很多时间调查这个问题,我想做一个总结.

I spend a lot of time to investigate that issue and I want to make a summary.

我们必须在 SettingsActivity 中重写 IsValidFragment 方法:

We have to override IsValidFragment method in the SettingsActivity:

protected override bool IsValidFragment(string fragmentName)
{
    return fragmentName == "droid.examples.preferences.SettingsActivity.SettingsFragment";
}

我的 SettingsActivity 扩展了 PreferenceActivity.感谢@Jeremy 关于实现 IOnPreferenceStartFragmentCallback 的建议,我发现基类已经扩展了它.

My SettingsActivity extends PreferenceActivity. Thanks to @Jeremy advice about implementation of IOnPreferenceStartFragmentCallback I find out that base class already extends it.

public abstract class PreferenceActivity ...
{
    ...
    public virtual bool OnPreferenceStartFragment(PreferenceFragment caller, Preference pref);
    ...
}

所以,我可能需要使用 PreferenceFragment 而不是 PreferenceFragmentCompat 来使代码保持一致:

So, I probably need to use PreferenceFragment instead of PreferenceFragmentCompat to make code consistent:

public class SettingsFragment : PreferenceFragment
{
    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        AddPreferencesFromResource(Resource.Xml.app_preferences_for_header);
    }
}

此外,我们还必须为片段添加 Register 属性:

Also we have to add Register attribute to our fragment:

[Register("droid.examples.preferences.SettingsActivity.SettingsFragment")]
public class SettingsFragment : PreferenceFragment
{
}

最后我更新了preference_headers.xml

Finally I updated preference_headers.xml

<?xml version="1.0" encoding="utf-8" ?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
  <header android:fragment="droid.examples.preferences.SettingsActivity.SettingsFragment"
          android:title="Prefs 1"
          android:summary="An example of some preferences." />
</preference-headers>

android:fragment 属性值可以包含 '$' 但 '+' 不起作用,因为 Register 不支持它,我们会得到编译错误.

android:fragment attribute value can contains '$' but '+' won't work because Register doesn't support it and we will get compilation error.

感谢所有帮助我的人

这篇关于如何在首选项标头中使用 PreferenceFragmentCompat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆