I am trying to implement preferences with sub-screens using AppCompatActivity and support.v7.preference
According to the docs, every PreferenceScreen within another PreferenceScreen functions as a sub-screen, and the framework will handle displaying it when clicked. http://developer.android.com/guide/topics/ui/settings.html#Subscreens
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- opens a subscreen of settings -->
<PreferenceScreen
android:key="button_voicemail_category_key"
android:title="@string/voicemail"
android:persistent="false">
<ListPreference
android:key="button_voicemail_provider_key"
android:title="@string/voicemail_provider" ... />
<!-- opens another nested subscreen -->
<PreferenceScreen
android:key="button_voicemail_setting_key"
android:title="@string/voicemail_settings"
android:persistent="false">
...
</PreferenceScreen>
<RingtonePreference
android:key="button_voicemail_ringtone_key"
android:title="@string/voicemail_ringtone_title"
android:ringtoneType="notification" ... />
...
</PreferenceScreen>
...
</PreferenceScreen>
This works fine using native Activity, PreferenceFragment... but using AppCompatActivity and PreferenceFragmentCompat, clicking the Preference element just highlights it, but doesn't open the sub-screen.
I couldn't find anything on this reading the docs and the code... do I need to implement any additional callbacks?
EDIT: just for completeness...
This works and opens the sub-screen:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new DemoPreferenceFragment())
.commit();
}
}
static public class DemoPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
This doesn't work/open the sub-screen:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(android.R.id.content, new DemoPreferenceFragment())
.commit();
}
}
static public class DemoPreferenceFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.preferences);
}
}
}
Edit: 25/01/2016
After fiddling with support.v7.preference for a few days, I've summed up my findings here, hoping it may help others: HowTo use support.v7.preference with AppCompat and potential drawbacks
It looks like a bug in PreferenceFragmentCompat or insufficiency of docs. It has method onNavigateToScreen which is called when you click on PreferenceScreen item.
But method getCallbackFragment() returns null by default, so you need override it in your fragment to return this. Also you need to implement PreferenceFragmentCompat.OnPreferenceStartScreenCallback.
But it leads to another problem when you can't get back to your initial PreferenceScreen,
Another way is to replace fragment which is described here How to move back from Preferences subscreen to main screen in PreferenceFragmentCompat?
Overriding PreferenceFragmentCompat.OnPreferenceStartScreenCallback
and adding the following to my preference fragment saved my day
My preference version is
It seems Google finally decides to support this in the newly released AndroidX preference 1.1.0-alpha.
This video from Android Dev Summit covers something about preference sub screen.
One extremely important thing you need you remember:
Your PreferenceScreen must contain :
Otherwise, it will not work. I've spent hours with thí
This is complete working example, I hope this will be helpful to someone.It covers opening the preference subscreen and moving back to main Settings screen.
I followed this issue in Android open source issue tracker --here
The official documentation is missing the documentation for loading preference subscreen—Refer here for official documentation--
The main advanced settings screen has 2 checkboxes and a disabled subscreen title(custom Pattern Settings):-
Once we check the Custom checkbox, the subscreen title is enabled.
On click of Custom pattern settings, the subscreen opens in new screen
Here is the example code with documentation:--
In res/xml/preferences.xml file:--
MainActivity.java should implement interface
PreferenceFragmentCompat.OnPreferenceStartScreenCallback
and then override the method--onPreferenceStartScreen
For the main Settings screen(fragment):-
and finally for the loading of subscreen: