Tùy chọn Android: Làm cách nào để tải các giá trị mặc định khi người dùng không sử dụng màn hình tùy chọn?


119

Tôi đang sử dụng PreferenceActivity để cho phép người dùng đặt một số giá trị. Tôi đang cấp cho nó tệp xml với các tùy chọn đã xác định.

Tôi đã thiết lập tất cả android:defaultValue=""cho họ.

Khi tôi khởi động ứng dụng của mình, tôi cần các tùy chọn hoặc nếu chúng chưa được đặt theo cách thủ công, tôi muốn các giá trị mặc định:

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

Tuy nhiên, khi android:defaultValue="true"tôi vẫn nhận được false. Vì vậy, có vẻ như các defaultValues ​​được đặt trong XML không được sử dụng ở bất kỳ đâu ngoài khi khởi tạo màn hình tùy chọn.

Tôi không muốn mã hóa cứng các giá trị mặc định trong getBoolean()phương thức. Vì vậy, có cách nào để lấy các giá trị mặc định mà chỉ xác định các giá trị này ở một nơi không?

Câu trả lời:


169

câu hỏi này tương tự như câu hỏi của tôi:

khởi tạo-tùy chọn-từ-xml-trong-chính-hoạt động

Chỉ cần sử dụng mã này trong onCreatephương pháp:

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

Nó sẽ tải các tùy chọn của bạn từ XML và tham số cuối cùng ( readAgain) sẽ đảm bảo rằng các tùy chọn của người dùng sẽ không bị ghi đè. Điều đó có nghĩa là đặt readAgainđối số thành falsecó nghĩa là điều này sẽ chỉ đặt giá trị mặc định nếu phương thức này chưa bao giờ được gọi trong quá khứ, vì vậy bạn không cần phải lo lắng về việc ghi đè cài đặt của người dùng mỗi khi Hoạt động của bạn được tạo

Hãy xem PreferenceManager.setDefaultValues trong Android API để điều tra thêm.


Chúng tôi có thể sử dụng nó trên bất kỳ biến thể SharedPrefrence nào khác mà chúng tôi tạo không?
Amol Gupta,

8
Ngoài ra, Nếu App của bạn có nhiều điểm nhập cảnh, đặt nó vào onCreate()trong Application.
SD

2
Điều này không hoạt động nếu sử dụng boolean và mặc định là "false" vì sau đó mục nhập mặc định sẽ không được tạo trong Android 2.x. Lệnh gọi tới ".getBoolean (KEY, true)" sẽ luôn trả về true. Đối với Android 4.x, nó hoạt động.
Gunnar Bernstein

10
Đặt readAgainthành true không liên quan gì đến việc tùy chọn của người dùng bị ghi đè. Từ Javadoc: Lưu ý: điều này sẽ KHÔNG đặt lại các tùy chọn trở lại giá trị mặc định của chúng.
devconsole

1
Đối với những người gặp vấn đề với giải pháp này (nó không hoạt động hoặc hoạt động một phần hoặc không luôn luôn), hãy xem câu trả lời của Steve Waring bên dưới ( stackoverflow.com/a/25602205/4410376 ). Nhiều khả năng bạn có một số tệp shared-prefs, tức là android đang tạo một số tệp shared-prefs dựa trên cấu hình của bạn hoặc mã lộn xộn.
Hack06

27

Lưu ý rằng nếu bạn đang sử dụng
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

để truy xuất các tùy chọn bạn phải sử dụng để đặt giá trị mặc định!
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

Ví dụ:
PreferenceManager.setDefaultValues(this, PREFS_NAME, Context.MODE_PRIVATE, R.xml.preference, false);

Tôi hy vọng điều này có thể giúp ai đó.


13

trong câu trả lời được chấp nhận của Pixel:

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

nó được tuyên bố rằng falsecó nghĩa là các giá trị mặc định sẽ không bị ghi đè. Đây không phải là những gì nó làm, nó chỉ là một lá cờ hiệu quả để dừng phân tích cú pháp nếu ứng dụng của bạn có nhiều hơn một điểm vào. Rất tiếc, thử nghiệm không được thực hiện cho mỗi tệp tùy chọn, vì vậy nếu bạn có nhiều hơn một tệp tùy chọn, bạn phải viết mã truetrên tất cả trừ tệp đầu tiên.

Nếu bạn lo lắng về hiệu quả, bạn có thể viết mã như thế này.

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

Nếu bạn thêm nhiều tùy chọn chia sẻ hơn, chỉ cần đặt SPL thành một số cao.


2
Thay vào đó, bạn luôn có thể tạo hàng loạt tùy chọn xml mà bạn CHỈ sử dụng để đặt giá trị mặc định. Ví dụ, nếu bạn có R.xml.prefs_device, R.xml.prefs_testR.xml.prefs_admin. Bạn có thể tạo một file prefs có chứa tất cả các prefs từ trên: R.xml.prefs_for_loading_default_values. Sau đó, sử dụng nó với PreferenceManager.setDefaultValues(this, R.xml.prefs_for_loading_default_values, false);
Chantell Osejo

Về hiệu quả: nếu bạn gọi nó trong onCreate()một lớp con của Application(đã đăng ký trong tệp kê khai) thì nó sẽ chỉ được gọi một lần mỗi khi ứng dụng bắt đầu. Đối với hiệu suất, sẽ phù hợp hơn (nếu có) nếu không thực hiện phân tích cú pháp mỗi khi ứng dụng khởi động (thay vào đó chỉ khi khởi động lần đầu) và đây là những gì false. Vì vậy, câu hỏi nhiều hơn là liệu bạn có cần kiểm tra mỗi lần bắt đầu (ví dụ: khi các tùy chọn mới có thể được thêm vào) hoặc liệu nó có đủ nếu thực hiện trong lần bắt đầu đầu tiên (hoặc đặt lại tùy chọn).
user905686

2

Ví dụ mở rộng DialogPreferencetôi làm điều này:

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

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

mDefault có thể là:

  • mContext.getResources (). getString (attrs.getAttributeResourceValue (androidns, "defaultValue", 100));
  • một cái gì đó bạn đã lập chỉ mục trong R.

Ok, tôi hơi lạc lõng ở đây về những gì bạn đang cố gắng đạt được. Tôi không muốn gọi DialogPreference, tôi cần giá trị mặc định khi người dùng không sử dụng Preferences.
Peterdk

Thay vì sử dụng Preferences mặc định trong prefs.xml, bạn có thể tạo các lớp của riêng mình. Ví dụ: bạn có thể tạo DialogPreference mới mở rộng từ DialogPreference và ghi đè onSetInitialValue.
Macarse

0

Đồng thời đảm bảo rằng bạn chưa bao giờ sử dụng SharedPreferences trước đây. Để đảm bảo chúng không bị thay đổi (có nghĩa là setDefaultValues ​​(this, xml, false) không có tác dụng), hãy gỡ cài đặt Ứng dụng của bạn và tải lên lại để đảm bảo không có giá trị nào bị chạm vào. Điều này đã giúp tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.