How to create a PreferenceScreen in a PreferenceActivity? - android

Consider the following activity:
public class SettingsActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceScreen screen =
getPreferenceManager().createPreferenceScreen(this);
}
}
Android Studio shows a warning for the call to getPreferenceManager():
'getPreferenceManager()' is deprecated
This inspection reports where deprecated code is used in the specified inspection scope.
However, it does not describe what corrective action I should take to avoid the warning. I can't find any alternative for obtaining a reference to the PreferenceManager and I see no other way to create a PreferenceScreen.
My goal is to programatically populate the PreferenceActivity with preferences and their default values since these are generated at runtime and cannot be included in xml/preferences.xml.

Although getPreferenceManager() is deprecated in SettingsActivity, it is not deprecated in PreferenceFragment. Therefore, the correct way to create a PreferenceScreen is as follows:
public class SettingsActivity extends PreferenceActivity {
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceScreen screen =
getPreferenceManager().createPreferenceScreen(getActivity());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
}

Related

PreferenceScreen in PreferenceFragment closing on ScreenOrientation change

I got some nested PreferenceScreen in my PreferenceActivity, and under them a series of CheckBoxPreference.
Everything is working well but, whenever the device is rotated, the PreferenceActivity returns to the main PreferenceScreen, disregarding what nested preference screen the user was in.
This is exactly like in these previous SO questions, where the solution was to add a key to the PreferenceScreen:
When my PreferenceActivity rotates, it does not remember which
PreferenceScreen was open
How to prevent quitting from inner preference screen when there's a
configuration change
Nested Preference Screen closes on Screenorientation change in
Android
I've added keys to all my PreferenceScreen and the solution works, as long as I use the deprecated way:
public class Settings extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
The problem is I'm using a PreferenceFragment, like in this SO answer (and also here).
The code:
public class Settings extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getFragmentManager().
beginTransaction().
replace(android.R.id.content, new MyPreferenceFragment()).
commit();
}
public static class MyPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
}
So, how to keep inner PreferenceScreen open after screen orientation changes, if possible with the current code?
I see that for Preferences Google now recommends AppCompatActivity and PreferenceFragmentCompat, but I would prefer to not use any libraries, not even Google's, specially for only such a small detail.
I'm quite surprised this little problem managed to generate three SO questions while Android was under API 11, and none - that I can find at least - between API 11 and API 28, when PreferenceFragment was deprecated.
Anyways, I found the solution here in SO as well, in an answer to Android- deprecated method warning regarding PreferenceActivity.
The key is to check if (savedInstanceState == null) before adding the PreferenceFragment, like this:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (savedInstanceState == null)
getFragmentManager().
beginTransaction().
replace(android.R.id.content, new MyPreferenceFragment()).
commit();
}
Now the nested PreferenceScreen remains open when screen orientation changes, as long as it has an android:key value set in, of course.

Testing ListPreference

I'm trying to test android preferences, and I'm a bit confused as to how to achieve that result.
Here is my preference
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:id="#+id/numberListPreference"
android:defaultValue="3"
android:entries="#array/number_text"
android:entryValues="#array/number_value"
android:key="#string/pref_key"
android:summary="#string/pref_summary"
android:title="#string/pref_title" />
</PreferenceScreen>
I want to test that when I change the number in the displayed ListPreference, the SharedPreference is actually changed.
Right now, the code works, I'm just blocking on the testing part.
Here is part of my activity :
public class SettingActivity extends AppCompatActivity implements
SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
The problem is I have the classic "If the target view is not part of the view hierarchy" error.
Any help is welcomed.
Thx !
#Test
public void clickListPreference() throws Exception{
// Check if it is displayed
Context appContext = InstrumentationRegistry.getTargetContext();
onData(allOf(
is(instanceOf(Preference.class)),
withKey(appContext.getResources().getString(R.string.pref_key))))
.check(matches(isDisplayed()));
// Check if click is working
onData(allOf(
is(instanceOf(Preference.class)),
withKey(appContext.getResources().getString(R.string.pref_key))))
.onChildView(withText(appContext.getResources()
.getString(R.string.pref_title))).perform(click());
}
Hope this will help you... Put your shared preference under click action

PreferenceManager.setDefaultValues in a PreferenceFragment

I have a PreferenceFragment and I want to set the default values according to an XML file. Here is my onCreate method:
public class SettingsFragment extends PreferenceFragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
//This is the faulty line
PreferenceManager.setDefaultValues(this, R.xml.preferences, true);
}
Unfortunately, it does not compile because "this" is not a proper context.
How should this be done?
This is because the first parameter of setDefaultValues is a Context. A PreferenceFragment is not a Context so use this.
PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, true);
use getActivity() as you are in a fragment, not a Context.
You will have to use getActivity() to get a Context inside a Fragment. Note that you can only use this Method safely after onActivityCreated(Bundle) was called by the system.
So you might want to use something like the following:
public class SettingsFragment extends PreferenceFragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
//This was the faulty line
PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, true);
}
}

Preferences activity deprecated

I am doing an app with preferences but I have used a method that is deprecated and it says :
"This function is not relevant for a modern fragment-based PreferenceActivity". My code is this:
public class Settings extends PreferenceActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
How can I update this to not deprecated function. Thank you very much.
The new way is to do the Preferences in an Fragment instead of an Activity. This is espacially true for large screens and tablets. Fragments can be shown separate or next to each other over an Activity according to screen size. Use them like this:
public static class YourPreferenceFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
}
and instead of calling the PreferenceActivity you make a call to the Fragment in your Activity:
YourPreferenceFragment prefFragment = new YourPreferenceFragment();
prefFragment.show(getFragmentManager(), "someFragmentId");
Try to use PreferenceFragment instead.
Check this: http://developer.android.com/guide/topics/ui/settings.html
PreferenceActivity is depricated, you can use PreferenceFragment instead.
here are some tutorials
Link 1
Link 2
Here is the documenattion for PreferenceFragment

android - changing ListPreference value from an Activity

Following the new API's I have created a pretty simple PreferenceFragment:
public class PrefsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
I use that in my Activity created to enable the user to change app settings:
public class SetPreferenceActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new PrefsFragment()).commit();
}
}
Now I need to change the summary of a ListPreference according to user's choice. There is no findPreference() method defined for Activity class, so how can I access the desired preference?
Sorry if the answer is obvious, I'm not really familiar with the new API and always used a PreferenceActivity before it became deprecated..
Instead of doing new PrefsFragment() right in your statement where you replace the fragment you can do this.
PreferenceFragment pFrag = new PrefsFragment();
PrefsFragment pf = (PrefsFragment)pFrag;
getFragmentManager().beginTransaction()
.replace(android.R.id.content, pFrag).commit();
then in your PreferenceFragment you create a public method that you can change what you want
pf.changeMyPreference();

Categories

Resources