Skip to content Skip to sidebar Skip to footer

How To Use Preferencefragmentcompat In The Preference Header

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 d

Solution 1:

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

We have to override IsValidFragment method in the SettingsActivity:

protectedoverrideboolIsValidFragment(string fragmentName)
{
    return fragmentName == "droid.examples.preferences.SettingsActivity.SettingsFragment";
}

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

public abstract classPreferenceActivity ...
{
    ...
    publicvirtualboolOnPreferenceStartFragment(PreferenceFragment caller, Preference pref);
    ...
}

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

publicclassSettingsFragment : PreferenceFragment
{
    publicoverridevoidOnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        AddPreferencesFromResource(Resource.Xml.app_preferences_for_header);
    }
}

Also we have to add Register attribute to our fragment:

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

Finally I updated preference_headers.xml

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

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

Thanks everyone who tried to help me

Solution 2:

Looks like the string you provide is just a message to send to your parent activity. Your parent activity is responsible for instantiating the right Fragment, and performing the ceremony to render it.

The platform docs seem to indicate as such:

When a user taps a Preference with an associated Fragment, the interface method PreferenceFragmentCompat.OnPreferenceStartFragmentCallback.onPreferenceStartFragment() is called

At time of writing, there's a code snippet on that page, which I've translated for my own project more-or-less as follows:

// This has to go in the activity which hosts the PreferenceFragment// which owns the Preference that has the `android:fragment` attribute.using Android.Support.V7.Preferences;
using Android.Support.V4.App;
partialclassMyActivity :
   PreferenceFragmentCompat.IOnPreferenceStartFragmentCallback
{

   Fragment GetFragmentForPrefString(string prefFragment)
   {
      // you implement this
   }
   constint fragmentContainerId = Resource.Id.whatever;

   publicboolOnPreferenceStartFragment(
      PreferenceFragmentCompat caller, Preference pref)
   {
      string prefString = pref.Fragment;
      var transaction = SupportFragmentManager.BeginTransaction();
      transaction.Replace(fragmentContainerId,
         GetFragmentForPrefString(prefString));

      // you'll probably also want to add it to the back stack,// but it's not strictly necessary I guess.

      transaction.Commit();
      returntrue;
   }
}

Their sample involves the Java API method getSupportFragmentManager().getFragmentFactory() which doesn't appear to be part of the V28 Xamarin support NuGet packages. But honestly I'm not sure why that level of indirection is necessary; I'd suggest you simply implement something like

switch (prefFragmentName)
{
   case"Fragment 1":
      returnnewFragment1();
// etc

Post a Comment for "How To Use Preferencefragmentcompat In The Preference Header"