Reputation: 940
I am building a Preference Activity where most of the preferences in the list will be executing code and not modifying a SharedPreference directly. My preferences.xml file looks like this.
<PreferenceCategory
android:title="Connection" >
<Preference
android:id="@+id/settings_connectToNewComputer"
android:key="connectToNewComputer"
android:summary="Currently connected to:"
android:title="Connect to new computer" />
<Preference
android:id="@+id/removeDevice"
android:key="removeDevice"
android:summary="Remove this device from the computer's whitelist"
android:title="Remove this device from computer" />
</PreferenceCategory>
<PreferenceCategory
android:title="About" >
<Preference
android:id="@+id/settings_About"
android:key="about"
android:summary="About me and my thanks to those who made this app great"
android:title="About Hue Pro" />
<Preference
android:id="@+id/contact"
android:key="contact"
android:summary="Contact me with comments, bugs, and suggestions for updates"
android:title="Contact me" />
</PreferenceCategory>
My goal is to have a block of code executed when a one of these preferences are clicked. Similar to the "Clear search history" in the Google Play settings preference menu. (https://i.sstatic.net/HgEE4.png)
Does anyone know how to make this possible?
I have to add that I have tried using findPreference("KeyNameHere") but it always returns null.
Thank you!
Edit:
I added in this code and implemented OnPreferenceClickListener:
@Override
public boolean onPreferenceClick(Preference preference) {
return false;
}
But this method never gets called. Is there another way to do this?
Edit 2:
I have found that if I take out the PreferenceCategory tags so I am left with this:
<Preference
android:id="@+id/settings_connectToNewComputer"
android:key="connectToNewComputer"
android:summary="Currently connected to:"
android:title="Connect to new computer" />
<Preference
android:id="@+id/removeDevice"
android:key="removeDevice"
android:summary="Remove this device from the computer's whitelist"
android:title="Remove this device from computer" />
<Preference
android:id="@+id/settings_About"
android:key="about"
android:summary="About me and my thanks to those who made this app great"
android:title="About Hue Pro" />
<Preference
android:id="@+id/contact"
android:key="contact"
android:summary="Contact me with comments, bugs, and suggestions for updates"
android:title="Contact me" />
and call this:
getPreferenceScreen().setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
return false;
}
});
then I actually get a response from the click event. The only down side is I have to remove the preference grouping. Anyone know why this is and any way to fix it?
Upvotes: 23
Views: 35681
Reputation: 71
For Kotlin
your xml should look like this
<Preference
app:title="Contact me"
app:key="contact"/>
do not forget the key. Then in your Settings Activity find this class
class SettingsFragment : PreferenceFragmentCompat()
and add this code
override fun onPreferenceTreeClick(preference: Preference): Boolean {
val key = preference.key
return super.onPreferenceTreeClick(preference)
}
When you are done your code should look like this
class SettingsFragment : PreferenceFragmentCompat() {
override fun onPreferenceTreeClick(preference: Preference): Boolean {
val key = preference.key
return super.onPreferenceTreeClick(preference)
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
}
}
Upvotes: 0
Reputation: 2319
Others answers were not worked in Androidx for me. I implemented Settings from Android Developers guides
See below guide for implementing click listener
1) Implement PreferenceManager.OnPreferenceTreeClickListener in your settings fragment, like below code
import androidx.preference.PreferenceManager;
class SettingsFragment extends PreferenceFragmentCompat implements PreferenceManager.OnPreferenceTreeClickListener {
2) Override onPreferenceTreeClick inside your SettingsFragment
@Override
public boolean onPreferenceTreeClick(Preference preference) {
String key = preference.getKey();
switch (key) {
case "key1":
return true;
case "key2":
return true;
//codes
}
}
Upvotes: 9
Reputation: 4141
Your Preference object wont get null if you will find followings (copypasting from the project):
public class ImePreferences extends PreferenceActivity {
.....
@Override
protected boolean isValidFragment(String fragmentName) {
return Settings.class.getName().equals(fragmentName);
}
.....
public static class Settings extends InputMethodSettingsFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setInputMethodSettingsCategoryTitle(R.string.language_selection_title);
setSubtypeEnablerTitle(R.string.select_language);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.ime_preferences);
Preference pLcl = getPreferenceScreen().findPreference(getResources().getString(
R.string.dictionary_button));
pLcl.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
// handle click here
l.a("this is the click");
return true;
}
});
if(pLcl != null)
l.a(6576);
}
}
.....
}
Upvotes: 0
Reputation: 28179
Just override:
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
String key = preference.getKey();
...
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
Upvotes: 16
Reputation: 183
Maybe this could not be useful for OP, but could be useful for someone else. I'd like to write a sort of summary; in general, you can follow mainly three ways: 1) you can find your preference somewhere in your code with
Preference examplePreference = findPreference(KEY_EXAMPLE_PREFERENCE);
and then you can add a click listener and override its on click method with
examplePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
// handle click here
}
});
This has to be done for every preference whose clicks you want to listen to 2) You can implement Preference.OnPreferenceClickListener interface in your settings fragment/activity and override onPreferenceClick just once, by using a switch construct or a if-else if-else if-... construct and merging all the single handlings; it should be something like:
@Override
public boolean onPreferenceClick(Preference preference) {
switch (preference.getKey()) {
case KEY_EXAMPLE_PREFERENCE: {
// handle click here
}
break;
case ...
}
}
Then, you still have to find each preference but you can simply call on each of them
setOnPreferenceClickListener(this);
(I think the OP's implementation didn't work (his method wasn't called) because of this last part) we pass "this" as parameter because we implemented the click listener interface
3) (which I think is the easiest) you can override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
in your preference fragment/activity without implementing any other interface and there you can copy the switch of the if-else if-... construct of option 2); the main advantage in that you shouldn't need to find each preference and to call on them setOnPreferenceClickListener.
Hope this will be useful for someone!
Upvotes: 18
Reputation: 645
You could also find the preference and set the click listener.
Preference connectToNewComputer= findPreference("connectToNewComputer");
connectToNewComputer.setOnPreferenceClickListener(this);
Upvotes: 10
Reputation: 940
I came up with my own (what I believe is really messed up) solution; but it works.
for(int x = 0; x < getPreferenceScreen().getPreferenceCount(); x++){
PreferenceCategory lol = (PreferenceCategory) getPreferenceScreen().getPreference(x);
for(int y = 0; y < lol.getPreferenceCount(); y++){
Preference pref = lol.getPreference(y);
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener(){
@Override
public boolean onPreferenceClick(Preference preference) {
return false;
}
});
}
}
So what I have learned is there is a hierarchical system that works like: PreferenceScreen has children PreferenceCategory has children Preference, as you can see in the XML file. My problem was I could not set the preferences' onClickListeners directly from the PreferenceScreen. So I made two for loops that will get down to each Preference and set an OnPreferenceClickListener for each and every one of them. Messy, but works finally.
Upvotes: 8
Reputation: 18151
Implement OnPreferenceClickListener
and in the onPreferenceClick
@Override
public boolean onPreferenceClick (Preference preference)
{
String key = preference.getKey();
// do what ever you want with this key
}
Upvotes: 17