Preferensi Android onclick event

111

Di preferensi.xml saya, saya memiliki elemen preferensi seperti ini:

<Preference android:title="About" />

Saya ingin menetapkan onClickacara, jadi jika pengguna akan mengkliknya, saya akan dapat membuka Intentbrowser atau baru . Saya mencoba melakukannya seperti yang saya lakukan dengan tombol, tetapi ini sepertinya tidak berhasil.

Badr Hari
sumber

Jawaban:

230

Badr,

Anda perlu mengatur android:keyuntuk item tersebut, Kemudian dalam kode Anda, Anda dapat melakukan ...

Dengan asumsi Anda menggunakan yang berikut ini dalam XML Anda:

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

Kemudian Anda dapat melakukan hal berikut di kode Anda:

Preference myPref = (Preference) findPreference("myKey");
myPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
             public boolean onPreferenceClick(Preference preference) {
                 //open browser or intent here
                 return true;
             }
         });
Will Tate
sumber
3
Di mana saya harus meletakkan ini? di SettingsActivity saya onPostCreatetidak akan berfungsi karena terlalu dini (Nullpointer-Exception). Bantuan apa pun dihargai
Wandang
1
findPreferencesudah ditinggalkan.
zackygaurav
6
PreferenceActivity.findPreferencesudah ditinggalkan. Namun dokumentasinya mengatakan "[T] fungsinya sekarang harus ditemukan di kelas PreferenceFragment baru. Jika Anda menggunakan PreferenceActivity dalam mode lamanya, dokumentasi di sana berlaku untuk API yang tidak digunakan lagi di sini.", Dan PreferenceFragment.findPreferencetidak dihentikan (seperti API level 23, saat ini pada saat penulisan). Jadi, findPreferenceitu sendiri tidak ditinggalkan; itu penggunaan langsung PreferenceActivityyang tidak digunakan lagi. Google ingin kita pindah ke PreferenceFragment, bukan untuk meninggalkan findPreference.
Mike Playle
Masuk onPreferenceClick, kembali truejika klik ditangani lain false.
Thupten
Ini berfungsi untuk saya dengan PreferenceFragmentCompatDividers.
Joseph Lam
59

meluncurkan situs web:

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

untuk meluncurkan aktivitas tertentu:

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

Anda juga dapat menggunakan "android: mimetype" untuk menyetel mimetype tersebut.

jason gilbert
sumber
1
Saya setuju, pendekatan ini lebih baik, terutama karena tidak menggunakan metode findPreference (String key) yang sekarang tidak digunakan lagi dan karena secara keseluruhan lebih bersih.
Lyallcooper
Sangat bagus, tetapi apakah mungkin juga membuat IntentChooser dengan cara ini?
Peterdk
@jasongilbert Apakah mungkin mengirim siaran dengan ACTION daripada memulai aktivitas dari klik preferensi?
Sazzad Hissain Khan
1
@jasongilbert Haruskah saya menentukan apa pun intent-filterdi manifes untuk SomeActivity, karena saya mendapatkan ActivityNotFoundException:(
theapache64
11

Anda perlu menggunakan acara onPreferenceTreeClick.

Misalnya lihat 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; 
        } 
    } 
Pentium10
sumber
Tautannya
6

UPDATE 2018+ Hari ini, findPreferencemetode ini dikosongkan. Jadi, untuk mencapai ini, cukup ganti onPreferenceTreeClickmetode di fragmen Preferensi Anda. Sebagai contoh:

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

Selain itu, jika Anda perlu untuk menangani klik di dalam elemen preferensi tertentu (misalnya ListPreference), Anda harus mendaftarkan setOnPreferenceChangeListenerdalam onCreatemetode dari 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;
        }
    });
}
akelec
sumber
Apa perbedaan antara onPreferenceClickdan onPreferenceTreeClick ?
Yousha Aleayoub
3

Tindak lanjut atas jawaban @jason gilbert

Saya menggunakan targetSdkVersion 25 , dan jawabannya tidak berhasil, saya harus membungkus tag maksud dengan tag Preferensi. Contoh:

<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>
Malek Hijazi
sumber