49

I want to detect when a Preference contained in a ListView gets clicked, so that I can launch an intent to manage that selection.

I would have done like this in my layout XML file:

<Preference android:title="About" android:key="myKey"></Preference>

And the following in my java code:

Preference myPref = (Preference) findPreference("myKey");
myPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
             public boolean onPreferenceClick(Preference preference) {
                 //open browser or intent here
             }
         });

But the method public Preference findPreference (CharSequence key) is deprecated.

  1. Is there a non deprecated equivalent?
  2. If not, what if I use it anyway?
  3. How can Fragments help me do my task in a better way? Check here: Preferences without deprecated methods.

Here you can check the XML layout structure that my activity has, and a snapshot of the application:

XML:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <Preference
        android:key="about"
        android:title="@string/titleAbout"
        android:summary="@string/summaryAbout"
    />

    <Preference
        android:key="labelTaxonomy"
        android:title="@string/titleLabelTaxonomy"
        android:summary="@string/summaryLabelTaxonomy"
    />

</PreferenceScreen>

SNAPSHOT:

snapshopt

After clicking on the About (or Access Label Taxonomy) Preference, I'd like to open an intent of some kind (could also be a video or anything else...the names are misleading).

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Matteo
  • 7,924
  • 24
  • 84
  • 129
  • I have a problem similar to yours. I do a bunch of things in Preferences (that probably I shouldn't), and I do need `findPreference()` to do some java on clicks. Not sure how to handle this now without heavily changing the whole thing, or ignoring the deprecation. :/ – Luis A. Florit Sep 30 '21 at 14:37

4 Answers4

64

Is there a non deprecated equivalent?

If you are using PreferenceFragment on API Level 11+ devices, you would call findPreference() on it. Otherwise, call findPreference() on your PreferenceActivity, as you have no choice.

If not, what if I use it anyway?

It will work.

How can Fragments help me do my task in a better way?

API Level 11+ introduced PreferenceFragment as another way of constructing the contents of a PreferenceActivity. You are welcome to use them, but if you are still supporting older devices, you cannot use PreferenceFragment for those devices.

That being said:

I want to detect when a Preference contained in a ListView gets clicked, so that I can launch an intent to manage that selection.

You do not need Java code for this. Use:

    <PreferenceScreen
            android:title="@string/title_intent_preference"
            android:summary="@string/summary_intent_preference">

        <intent android:action="android.intent.action.VIEW"
                android:data="http://www.android.com" />

    </PreferenceScreen>

(as seen in the JavaDocs for PreferenceActivity)

This will create an entry in the preference UI that, when clicked, will start an activity with the specified Intent.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thks a lot, just two other questions: 1) I have many preferences entries inside of my , can I still use the `XML` approach you are suggesting in the snippet just for one single `Preference` entry?and how? 2) Suppose I want to use a new `intent`, I'm forced to used some java code to create it, correct? I hope you can help me, Thks again! ;D – Matteo Jun 30 '12 at 12:04
  • @Matteo: 1) Read the JavaDocs that I linked to, and see the example of the use of this `` approach in and among other preferences. 2) I have no idea what "a new `intent`" means in this case. – CommonsWare Jun 30 '12 at 12:18
  • 1) Thks... 2) Let me explain better: it seemed to me that the intent described in your `XML` snippet is only for visiting a website by opening the browser. Suppose I want to launch an intent opening another activity, or displaying a video from the gallery of the phone, or anything else, I should define the new intent in the standard Java way, correct? – Matteo Jun 30 '12 at 12:23
  • @Matteo: IMHO, preferences should not be leading to random places. Preferences are for *preferences*, not for displaying videos. The purpose of `` is if you have something that logically is part of the app's settings but cannot readily be rendered using the standard preference UI. That being said, if your `Intent` is not static, you will need to handle it via Java, probably using code along the lines of what you have in your question. – CommonsWare Jun 30 '12 at 12:45
  • I c...!So I should not use `Preferences` in the way I'm doing?(You can check the added part of the question)...If not what kind of class should I use instead?Thks so much for you help, and sorry if it's a stupid question, I'm a beginner in android... ;D – Matteo Jun 30 '12 at 12:53
  • @Matteo: I would just have "About" be in your options menu or the overflow menu of the action bar. – CommonsWare Jun 30 '12 at 13:30
  • And what class should I use instead for the other entries? a `ListActivity`? – Matteo Jun 30 '12 at 13:52
  • @Matteo: Since I don't know what "Access Label Taxonomy" is supposed to do, I cannot answer that question, sorry. – CommonsWare Jun 30 '12 at 14:01
  • It should launch an intent visualising a video, or opening the browser, or anything like that. Thks for your help, really! – Matteo Jun 30 '12 at 14:10
5

If you use fragments, you can use the method "findPreference()" on the basis of a preferences fragment.

public class CustomActivity extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_custom);

      CustomFragment customFragment = (CustomFragment) getFragmentManager().findFragmentById(R.id.custom_fragment);
      EditTextPreference textPreference = (EditTextPreference) customFragment.findPreference("preference_key");

      textPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
         public boolean onPreferenceClick(Preference preference) {
             //open browser or intent here
         }
     });
  }
}
kaffee_kocher
  • 71
  • 2
  • 6
2

2018 UPDATE Today, the onPreferenceTreeClick method has to be overriden in the Preference fragment for this purpose. For example:

public class MySettingsFragment extends PreferenceFragment {

    @Override
    public boolean onPreferenceTreeClick (PreferenceScreen preferenceScreen,
                                          Preference preference)
    {
        String key = preference.getKey();
        if(key.equals("someKey")){
            // do your work
            return true;
        }
        return false;
    }
}
akelec
  • 3,797
  • 3
  • 41
  • 39
1

maybe docs link are not clear. But using that feature is very simple. for example, you can use that as a twitter page like this

<PreferenceCategory android:title="Share" >
 <PreferenceScreen
        android:title="Twitter"
        android:summary="Follow me at Twitter">

    <intent android:action="android.intent.action.VIEW"
            android:data="https://twitter.com/" />

</PreferenceScreen>
</PreferenceCategory>

it doesnt need any java code. Thanks to CommonsWare!

mehmet
  • 1,558
  • 5
  • 30
  • 41