Evento onclick de preferencias de Android


111

En mis preferencias.xml tengo un elemento de preferencia como este:

<Preference android:title="About" />

Quiero asignar un onClickevento, por lo que si el usuario hace clic en él, podría abrir un nuevo Intento un navegador. Traté de hacerlo como lo hago con los botones, pero no parece funcionar.

Respuestas:


230

Badr,

Debe configurar android:keyel artículo, luego en su código puede hacer ...

Suponiendo que usa lo siguiente en su XML:

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

Entonces puedes hacer lo siguiente en tu código:

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

3
¿Dónde debo colocar esto? en mi SettingsActivity en onPostCreateno funcionará porque es demasiado pronto (Nullpointer-Exception). Se agradece cualquier ayuda
Wandang

1
findPreferencees obsoleto.
zackygaurav

6
PreferenceActivity.findPreferencees obsoleto. Sin embargo, la documentación dice "[E] sta funcionalidad ahora debería encontrarse en la nueva clase PreferenceFragment. Si está utilizando PreferenceActivity en su modo anterior, la documentación se aplica a las API obsoletas aquí", y PreferenceFragment.findPreferenceno está obsoleta (a partir de API nivel 23, actual en el momento de escribir este artículo). Entonces, en findPreferencesí mismo no está desaprobado; es el uso directo del PreferenceActivityque está en desuso. Google quiere que nos PreferenceFragmentmudemos, no que abandonemos findPreference.
Mike Playle

En onPreferenceClick, regrese truesi el clic se manejó de otra manera false.
Thupten

Esto me funciona con PreferenceFragmentCompatDividers.
Joseph Lam

59

para lanzar un sitio web:

<PreferenceScreen android:title="website">
    <intent
        android:action="android.intent.action.VIEW"
        android:data="http://www.example.com"
        />
</PreferenceScreen>

para lanzar una actividad específica:

<PreferenceScreen android:title="something">
    <intent
        android:action="android.intent.action.MAIN"
        android:targetPackage="com.example.foo"
        android:targetClass="com.example.foo.SomeActivity"
        />
</PreferenceScreen>

también puede usar "android: mimetype" para configurar el mimetype.


1
Estoy de acuerdo, este enfoque es mejor, especialmente porque no usa el método findPreference (String key) ahora obsoleto y porque es más limpio en general.
lyallcooper

Muy bien, pero ¿también es posible crear un IntentChooser de esta manera?
Peterdk

@jasongilbert ¿Es posible enviar una transmisión con ACCIÓN en lugar de iniciar la actividad desde el clic de preferencia?
Sazzad Hissain Khan

1
@jasongilbert ¿Debo especificar alguno intent-filteren el manifiesto para el SomeActivity, porque estoy obteniendo ActivityNotFoundException:(
theapache64

11

Debe utilizar el evento onPreferenceTreeClick.

Por ejemplo, consulte http://www.javased.com/index.php?source_dir=platform_packages_apps_phone/src/com/android/phone/MobileNetworkSettings.java

 @Override 
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 
        /** TODO: Refactor and get rid of the if's using subclasses */ 
        if (mGsmUmtsOptions != null && 
                mGsmUmtsOptions.preferenceTreeClick(preference) == true) { 
            return true; 
        } else if (mCdmaOptions != null && 
                   mCdmaOptions.preferenceTreeClick(preference) == true) { 
            if (Boolean.parseBoolean( 
                    SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) { 

                mClickedPreference = preference; 

                // In ECM mode launch ECM app dialog 
                startActivityForResult( 
                    new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null), 
                    REQUEST_CODE_EXIT_ECM); 
            } 
            return true; 
        } else if (preference == mButtonPreferredNetworkMode) { 
            //displays the value taken from the Settings.System 
            int settingsNetworkMode = android.provider.Settings.Secure.getInt(mPhone.getContext(). 
                    getContentResolver(), android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, 
                    preferredNetworkMode); 
            mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode)); 
            return true; 
        } else if (preference == mButtonDataRoam) { 
            if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam."); 

            //normally called on the toggle click 
            if (mButtonDataRoam.isChecked()) { 
                // First confirm with a warning dialog about charges 
                mOkClicked = false; 
                new AlertDialog.Builder(this).setMessage( 
                        getResources().getString(R.string.roaming_warning)) 
                        .setTitle(android.R.string.dialog_alert_title) 
                        .setIconAttribute(android.R.attr.alertDialogIcon) 
                        .setPositiveButton(android.R.string.yes, this) 
                        .setNegativeButton(android.R.string.no, this) 
                        .show() 
                        .setOnDismissListener(this); 
            } else { 
                mPhone.setDataRoamingEnabled(false); 
            } 
            return true; 
        } else if (preference == mButtonDataEnabled) { 
            if (DBG) log("onPreferenceTreeClick: preference == mButtonDataEnabled."); 
            ConnectivityManager cm = 
                    (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 

            cm.setMobileDataEnabled(mButtonDataEnabled.isChecked()); 
            return true; 
        } else if (preference == mLteDataServicePref) { 
            String tmpl = android.provider.Settings.Secure.getString(getContentResolver(), 
                        android.provider.Settings.Secure.SETUP_PREPAID_DATA_SERVICE_URL); 
            if (!TextUtils.isEmpty(tmpl)) { 
                TelephonyManager tm = (TelephonyManager) getSystemService( 
                        Context.TELEPHONY_SERVICE); 
                String imsi = tm.getSubscriberId(); 
                if (imsi == null) { 
                    imsi = ""; 
                } 
                final String url = TextUtils.isEmpty(tmpl) ? null 
                        : TextUtils.expandTemplate(tmpl, imsi).toString(); 
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 
                startActivity(intent); 
            } else { 
                android.util.Log.e(LOG_TAG, "Missing SETUP_PREPAID_DATA_SERVICE_URL"); 
            } 
            return true; 
        } else { 
            // if the button is anything but the simple toggle preference, 
            // we'll need to disable all preferences to reject all click 
            // events until the sub-activity's UI comes up. 
            preferenceScreen.setEnabled(false); 
            // Let the intents be launched by the Preference manager 
            return false; 
        } 
    } 

El enlace es 404
JZAU

6

ACTUALIZACIÓN 2018+ Hoy, el findPreferencemétodo está depurado. Entonces, para lograr esto, simplemente anule el onPreferenceTreeClickmétodo en su fragmento de Preferencia. Por ejemplo:

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;
    }
}

Además, si necesita manejar un clic dentro de un elemento de preferencia particular (por ejemplo ListPreference), debe registrar setOnPreferenceChangeListenerel onCreatemétodo dentro del MySettingsFragment:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Load the preferences from an XML resource
    addPreferencesFromResource(R.xml.preferences);

    // register listener
    final Preference prefList = findPreference("key");
    prefList.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        public boolean onPreferenceChange(Preference preference, Object value) {
            System.out.println("Selected: " + value);
            return true;
        }
    });
}

¿Cuál es la diferencia entre onPreferenceClicky onPreferenceTreeClick ?
Yousha Aleayoub

3

Un seguimiento de la respuesta de @jason gilbert

Estoy en targetSdkVersion 25 y su respuesta no funcionó, tuve que envolver la etiqueta de intención con una etiqueta de preferencia. Ejemplo:

<PreferenceScreen android:title="something">
    <Preference title="Title">
       <intent
       android:action="android.intent.action.MAIN"
       android:targetPackage="com.example.foo"
       android:targetClass="com.example.foo.SomeActivity"
       />
    </Preference>
</PreferenceScreen>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.