Preferensi Android: Bagaimana cara memuat nilai default ketika pengguna belum menggunakan layar preferensi?

119

Saya menggunakan PreferenceActivity agar pengguna dapat menyetel beberapa nilai. Saya memberinya file xml dengan preferensi yang ditentukan.

Saya telah mengatur semua android:defaultValue=""untuk mereka.

Ketika saya memulai aplikasi saya, saya memerlukan preferensi, atau jika mereka belum diatur secara manual, saya ingin nilai default:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean value = prefs.getBoolean("key"), false); 

Namun, saat itu android:defaultValue="true"saya masih mendapatkan false. Jadi, sepertinya defaultValues ​​yang disetel dalam XML tidak digunakan di mana pun kecuali saat menginisialisasi layar preferensi.

Saya tidak ingin melakukan hardcode nilai default dalam getBoolean()metode ini. Jadi, apakah ada cara untuk mendapatkan nilai default dengan hanya mendefinisikan ini di 1 tempat?

Peterdk
sumber

Jawaban:

169

pertanyaan ini mirip dengan pertanyaan saya:

inisialisasi-preferensi-dari-xml-in-main-activity

Cukup gunakan kode ini dalam onCreatemetode:

PreferenceManager.setDefaultValues(this, R.xml.preference, false);

Ini akan memuat preferensi Anda dari XML, dan parameter terakhir ( readAgain) akan menjamin bahwa preferensi pengguna tidak akan ditimpa. Itu berarti menyetel readAgainargumen menjadi falseberarti ini hanya akan menyetel nilai default jika metode ini belum pernah dipanggil sebelumnya sehingga Anda tidak perlu khawatir menimpa setelan pengguna setiap kali Aktivitas Anda dibuat

Lihat PreferenceManager.setDefaultValues di Android API untuk penyelidikan lebih lanjut.

piksel
sumber
Bisakah kita menggunakan ini di atas variabel SharedPrefrence lain yang kita buat?
Amol Gupta
8
Juga, Jika App Anda memiliki beberapa entry point, tempatkan dalam onCreate()dari Application.
SD
2
Ini tidak berfungsi jika menggunakan boolean dan default ke "false" karena entri default tidak akan dibuat di Android 2.x. Panggilan ke ".getBoolean (KEY, true)" akan selalu mengembalikan true. Untuk Android 4.x berfungsi.
Gunnar Bernstein
10
Menyetel readAgainke benar tidak ada hubungannya dengan preferensi pengguna yang ditimpa. Dari Javadoc: Catatan: ini TIDAK akan mengatur ulang preferensi kembali ke nilai defaultnya.
devconsole
1
Bagi mereka yang memiliki masalah dengan solusi ini (tidak berfungsi atau berfungsi sebagian atau tidak selalu) lihat jawaban Steve Waring di bawah ini ( stackoverflow.com/a/25602205/4410376 ). Kemungkinan besar Anda memiliki beberapa file shared-prefs, misalnya android membuat beberapa file shared-prefs berdasarkan konfigurasi atau kode yang berantakan.
Hack06
27

Ketahuilah bahwa jika Anda menggunakan
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

untuk mengambil preferensi yang harus Anda gunakan untuk menyetel default!
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

Sebagai contoh:
PreferenceManager.setDefaultValues(this, PREFS_NAME, Context.MODE_PRIVATE, R.xml.preference, false);

Saya harap ini dapat membantu seseorang.

Francesco Vadicamo
sumber
13

dalam jawaban Pixel yang diterima:

PreferenceManager.setDefaultValues(this, R.xml.preference, false);

dinyatakan bahwa falsecara default tidak akan ditimpa. Bukan ini yang dilakukannya, ini hanyalah tanda efisiensi untuk menghentikan penguraian jika aplikasi Anda memiliki lebih dari satu titik masuk. Sayangnya pengujian tidak dilakukan per file preferensi, jadi jika Anda memiliki lebih dari satu file preferensi, Anda harus membuat kode truepada semua kecuali yang pertama.

Jika Anda khawatir tentang efisiensi, Anda dapat membuat kode seperti ini.

final static private int SPL = 1;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (sp.getInt("spl", 0) != SPL)
{
    PreferenceManager.setDefaultValues(this, R.xml.prefs1, true);
    PreferenceManager.setDefaultValues(this, R.xml.prefs2, true);
    sp.edit().putInt("spl", SPL).apply();
}

Jika Anda pernah menambahkan lebih banyak preferensi bersama, cukup setel SPL ke angka yang tinggi.

Steve Waring
sumber
2
Sebagai alternatif, Anda selalu dapat membuat preferensi massal.xml yang HANYA digunakan untuk menyetel nilai default. Misalnya, jika Anda memiliki R.xml.prefs_device, R.xml.prefs_test, dan R.xml.prefs_admin. Anda dapat membuat satu file prefs yang berisi semua prefs dari atas: R.xml.prefs_for_loading_default_values. Kemudian gunakan itu dengan PreferenceManager.setDefaultValues(this, R.xml.prefs_for_loading_default_values, false);
Chantell Osejo
Mengenai efisiensi: jika Anda memanggilnya dalam onCreate()subkelas Application(terdaftar di manifes), toh itu hanya akan dipanggil sekali setiap aplikasi dimulai. Untuk kinerja, akan lebih relevan (jika ada) untuk tidak melakukan parsing setiap kali aplikasi dimulai (alih-alih hanya pada permulaan pertama) dan inilah yang falsedilakukannya. Jadi ini lebih merupakan pertanyaan apakah Anda memerlukan pemeriksaan pada setiap permulaan (misalnya ketika preferensi baru mungkin ditambahkan) atau apakah itu cukup jika dilakukan pada permulaan pertama (atau preferensi disetel ulang).
pengguna905686
2

Misalnya memperpanjang DialogPreferencesaya melakukan ini:

@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
    super.onSetInitialValue(restore, defaultValue);

    if (restore) {
        mValue = shouldPersist() ? getPersistedString(mDefault) : mDefault;
    } else {
        mValue = mDefault;
    }
}

mDefault dapat berupa:

  • mContext.getResources (). getString (attrs.getAttributeResourceValue (androidns, "defaultValue", 100));
  • sesuatu yang telah Anda indeks di R.
Macarse
sumber
Oke, saya agak bingung di sini tentang apa yang ingin Anda capai. Saya tidak ingin memanggil DialogPreference, saya memerlukan nilai default ketika pengguna tidak menggunakan Preferensi.
Peterdk
Daripada menggunakan Preferensi default di prefs.xml Anda, Anda dapat membuat kelas Anda sendiri. Misalnya, Anda dapat membuat DialogPreference baru yang diperluas dari DialogPreference dan mengganti onSetInitialValue.
Macarse
0

Juga pastikan Anda belum pernah menggunakan SharedPreferences sebelumnya. Untuk memastikannya tidak diubah (yang berarti setDefaultValues ​​(ini, xml, false) tidak berpengaruh) hapus instalan Aplikasi Anda dan unggah lagi untuk memastikan tidak ada nilai yang tersentuh. Ini membantu saya.

wirthra
sumber