Reputation: 68474
I have an activity which extends PreferenceActivity. I'm loading preferences from the xml file. But in some cases i need completely hide one of the preferences from the screen based on my app state. There is a setEnabled method, but it's not exactly what i want. I want to remove that preference from the screen completely. Is it possible ?
Upvotes: 148
Views: 83654
Reputation: 444
Instead of doing this in onCreate in the settings activity:
getSupportFragmentManager().beginTransaction().replace(R.id.settings_container, new SettingsFragment()).commit();
You can initialize a global variable for the settings fragment and set it up like this:
settingsFragment = new SettingsFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.settings_container, settingsFragment).commit();
Then you can do something like this further down in onCreate to set what should be hidden based on existing preferences, or to change what is hidden/visible based on conditions in your OnSharedPreferenceChangeListener:
settingsFragment.findPreference("setting key").setVisible(false);
Upvotes: 0
Reputation: 300
There is a simple workaround:
//In your Activity code after finding the preference to hide:
if(pref!=null) {
pref.setEnabled(false);
pref.setSelectable(false);
//Following line will replace the layout of your preference by an empty one
pref.setLayoutResource(R.layout.preference_hidden);
}
And create a preference_hidden layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="0dp"/>
Wherever is your Preference to hide (in a PreferenceGroup or at root) it will work!
Upvotes: 2
Reputation: 1020
If all you need is not to show the preference i.e. hide the preference then do the following
findPreference<Preference>("keyName").isVisible = false
code is in kotlin
Note : This is AndroidX preferences (don't know if same with hold with earlier Preference)
Upvotes: 0
Reputation: 560
If you're doing what I think you're trying to do (because I'm trying to do it now) it might be better to enable/disable the preference. Because removing it takes it out of the preference screen and you might not be able to add it back where you want it if you made the screen programmatically.
pref.setEnabled(false); pref.setEnabled(true);
although this might be deprecated. It works for the use case that I'm going through right now.
Upvotes: 0
Reputation: 3659
If you want to evaluate, and based on that mask, an alternative may be
SwitchPreference autenticacionUsuario =
(SwitchPreference) findPreference("key_autenticacion_usuario");
final EditTextPreference Username =
(EditTextPreference) findPreference("key_username_mqtt");
final EditTextPreference Password =
(EditTextPreference) findPreference("key_password_mqtt");
if (!autenticacionUsuario.isChecked()) {
PreferenceCategory preferenceCategory =
(PreferenceCategory) findPreference("category_mqtt");
preferenceCategory.removePreference(Username);
preferenceCategory.removePreference(Password);
}
All this must be within
public static class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Upvotes: 0
Reputation: 14162
If you are using PreferenceFragmentCompat you can set the visiblity in xml.
The preferences in your xml will be converted to AppCompat versions automatically. You can then use the 'app:isPreferenceVisible' attribute in your xml
preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<CheckBoxPreference
android:defaultValue="false"
android:key="show.navigation"
android:title="Show navigation"
app:isPreferenceVisible="false" />
...
The attribute is documented at https://developer.android.com/guide/topics/ui/settings/components-and-attributes
Adding PreferenceFragmentCompat
is documented at https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy
Example:
public class MySettingsActivity extends AppCompatActivity {
public static class MySettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferences, rootKey);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, new MySettingsFragment())
.commit();
}
}
Upvotes: 21
Reputation: 3880
If your Preference
is within a PreferenceCategory
, you have to do this:
XML:
<PreferenceCategory
android:key="category_foo"
android:title="foo">
<CheckBoxPreference
android:key="checkPref" />
Java:
CheckBoxPreference mCheckBoxPref = (CheckBoxPreference) findPreference("checkPref");
PreferenceCategory mCategory = (PreferenceCategory) findPreference("category_foo");
mCategory.removePreference(mCheckBoxPref);
Upvotes: 219
Reputation: 256
I recommend using v7 preference, it has setVisible()
method. But I have not tried it yet. Accordingly you have to use PreferenceFragment
instead of PreferenceActivity
.
Upvotes: 7
Reputation: 166
In your XML file:
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="preferenceScreen">
<PreferenceCategory
android:key="personalisation"
android:title="your title here">
<ThemedPreference
android:key="animation" />
</PreferenceScreen>
In your code:
PreferenceScreen pPreferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");
PreferenceCategory pCategory = (PreferenceCategory) findPreference("personalisation");
ThemedPreference pThemePref = (ThemedPreference) findPreference("animation");
pPreferenceScreen.removePreference(pCategory); //remove category
pCategory.removePreference(pThemePref); // remove preference
Upvotes: 8
Reputation: 115952
You can do this in 2 ways:
1.If you use support library, you can build a map of the tree of preferences and their parents, and then remove a preference by using its parent. Here's a function to generate such a map:
public static Map<Preference, PreferenceGroup> buildPreferenceParentTree(@NonNull final PreferenceScreen preferenceScreen) {
final Map<Preference, PreferenceGroup> result = new HashMap<>();
final Stack<PreferenceGroup> curParents = new Stack<>();
curParents.add(preferenceScreen);
while (!curParents.isEmpty()) {
final PreferenceGroup parent = curParents.pop();
final int childCount = parent.getPreferenceCount();
for (int i = 0; i < childCount; ++i) {
final Preference child = parent.getPreference(i);
result.put(child, parent);
if (child instanceof PreferenceGroup)
curParents.push((PreferenceGroup) child);
}
}
return result;
}
Upvotes: 0
Reputation: 5900
Since Android API 26 getParent()
method is available: https://developer.android.com/reference/android/preference/Preference.html#getParent()
Though you can do the following:
preference.getParent().removePreference(preference);
Upvotes: 3
Reputation: 511
In the XML file you can make a hidden preference by leaving the title and summary tags empty.
<EditTextPreference
android:defaultValue="toddlerCam"
android:key="save_photo_dir"
/>
Upvotes: 3
Reputation: 42407
Here's a generic way to do this that works regardless of whether the preference is under a PreferenceCategory
or PreferenceScreen
.
private void removePreference(Preference preference) {
PreferenceGroup parent = getParent(getPreferenceScreen(), preference);
if (parent == null)
throw new RuntimeException("Couldn't find preference");
parent.removePreference(preference);
}
private PreferenceGroup getParent(PreferenceGroup groupToSearchIn, Preference preference) {
for (int i = 0; i < groupToSearchIn.getPreferenceCount(); ++i) {
Preference child = groupToSearchIn.getPreference(i);
if (child == preference)
return groupToSearchIn;
if (child instanceof PreferenceGroup) {
PreferenceGroup childGroup = (PreferenceGroup)child;
PreferenceGroup result = getParent(childGroup, preference);
if (result != null)
return result;
}
}
return null;
}
Upvotes: 2
Reputation: 371
If you want something that will dynamically change the prefs for example on a SwitchPreference, I have found the best way is to put all my sub options into two category containers. Initially you'll have everything shown, then you just remove the bits you don't want. The clever bit, is you just trigger recreate when something changes and then you don't have to manually create anything or worry about putting things back in in the correct order.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
PreferenceCategory prefCatOne= (PreferenceCategory)findPreference("prefCatOne");
PreferenceCategory prefCatTwo= (PreferenceCategory)findPreference("prefCatTwo");
SwitchPreference mySwitchPref= (SwitchPreference)findPreference("mySwitchPref");
PreferenceScreen screen = getPreferenceScreen();
if (mySwitchPref.isChecked()) {
screen.removePreference(prefCatOne);
} else {
screen.removePreference(prefCatTwo);
}
}
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("mySwitchPref")) {
this.recreate();
}
}
The only downside that I can see with this, is there is a flash as the screen is recreated from scratch.
Upvotes: 9
Reputation: 27105
In the case where the Preference is a direct child of the preference screen, here is some stand-alone code:
PreferenceScreen screen = getPreferenceScreen();
Preference pref = getPreferenceManager().findPreference("mypreference");
screen.removePreference(pref);
Upvotes: 54
Reputation: 129802
Yes, if you have a reference to both the Preference
, and its parent (a PreferenceCategory
, or PreferenceScreen
)
myPreferenceScreen.removePreference(myPreference);
Upvotes: 179