Android-Einstellungen onclick event


111

In meiner Einstellungen.xml habe ich ein Präferenzelement wie das folgende:

<Preference android:title="About" />

Ich möchte ein onClickEreignis zuweisen. Wenn der Benutzer darauf klicken würde, könnte ich ein neues Intentoder einen Browser öffnen . Ich habe versucht, es wie mit Knöpfen zu machen, aber das scheint nicht zu funktionieren.

Antworten:


230

Badr,

Sie müssen android:keyfür den Artikel festlegen , dann können Sie in Ihrem Code ...

Angenommen, Sie verwenden Folgendes in Ihrem XML:

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

Dann können Sie in Ihrem Code Folgendes tun:

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

3
Wo soll ich das platzieren? in meinen SettingsActivity onPostCreatefunktioniert nicht, weil es zu früh ist (Nullpointer-Exception). Jede Hilfe wird geschätzt
Wandang

1
findPreferenceist veraltet.
Zackygaurav

6
PreferenceActivity.findPreferenceist veraltet. In der Dokumentation heißt es jedoch "[T] seine Funktionalität sollte jetzt in der neuen PreferenceFragment-Klasse gefunden werden. Wenn Sie PreferenceActivity im alten Modus verwenden, gilt die Dokumentation dort für die veralteten APIs hier." Und PreferenceFragment.findPreferenceist nicht veraltet (ab API) Stufe 23, aktuell zum Zeitpunkt des Schreibens). Also findPreferenceselbst ist nicht veraltet; es ist die direkte Verwendung, PreferenceActivitydie veraltet ist. Google möchte, dass wir PreferenceFragmentstattdessen umziehen und nicht aufgeben findPreference.
Mike Playle

Geben Sie onPreferenceClickin zurück, truewenn der Klick anderweitig behandelt wurde false.
Thupten

Dies funktioniert bei PreferenceFragmentCompatDividers.
Joseph Lam

59

So starten Sie eine Website:

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

So starten Sie eine bestimmte Aktivität:

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

Sie können auch "android: mimetype" verwenden , um den Mimetyp festzulegen.


1
Ich stimme zu, dieser Ansatz ist besser, insbesondere weil er nicht die jetzt veraltete Methode findPreference (String key) verwendet und insgesamt nur sauberer ist.
Lyallcooper

Sehr schön, aber ist es auch möglich, auf diese Weise einen IntentChooser zu erstellen?
Peterdk

@jasongilbert Ist es möglich, eine Sendung mit ACTION zu senden, anstatt die Aktivität über einen Einstellungsklick zu starten?
Sazzad Hissain Khan

1
@ Jasongilbert Sollte ich eine intent-filterim Manifest für die angeben SomeActivity, weil ich bekomme ActivityNotFoundException:(
theapache64

11

Sie müssen das Ereignis onPreferenceTreeClick verwenden.

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

Der Link ist 404
JZAU

6

2018+ UPDATE Heute ist die findPreferenceMethode entzogen. Um dies zu erreichen, überschreiben Sie einfach die onPreferenceTreeClickMethode in Ihrem Einstellungsfragment. Beispielsweise:

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

Wenn Sie einen Klick innerhalb eines bestimmten Einstellungselements (z. B. ListPreference) ausführen müssen, sollten Sie außerdem setOnPreferenceChangeListenerdie onCreateMethode innerhalb der folgenden Methode registrieren 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;
        }
    });
}

Was ist der Unterschied zwischen onPreferenceClickund onPreferenceTreeClick ?
Yousha Aleayoub

3

Eine Fortsetzung der Antwort von @jason gilbert

Ich bin auf targetSdkVersion 25 und seine Antwort hat nicht funktioniert. Ich musste das Intent-Tag mit einem Preference-Tag versehen. Beispiel:

<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>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.