2012-04-12 22 views
15

Mặc dù nó đang được ghi lại bằng cách sử dụng "%s", tôi có thể hiển thị giá trị đã chọn dưới dạng tóm tắt, nó không hoạt động như mong đợi.Văn bản tóm tắt của ListPreference không được cập nhật tự động bất cứ khi nào có sự thay đổi trong lựa chọn

http://developer.android.com/reference/android/preference/ListPreference.html#getSummary%28%29

Tôi gặp sau preferences.xml

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 
    <PreferenceCategory 
     android:title="@string/preference_xxx_category"> 
     <CheckBoxPreference 
      android:title="@string/preference_xxx_mode_title" 
      android:defaultValue="false" 
      android:summary="@string/preference_xxx_mode_summary" 
      android:key="xxxModePreference" /> 
    </PreferenceCategory> 

    <PreferenceCategory 
     android:title="@string/preference_yyy_category"> 
     <ListPreference 
      android:title="@string/preference_yyy_mode_title" 
      android:defaultValue="0" 
      android:entries="@array/yyy" 
      android:entryValues="@array/yyy_values" 
      android:summary="%s" 
      android:key="yyyModePreference" />   
    </PreferenceCategory> 

</PreferenceScreen> 

và đây là tôi arrays.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string-array name="yyy"> 
     <item>Display value 0</item> 
     <item>Display value 1</item> 
    </string-array> 

    <string-array name="yyy_values"> 
     <item>0</item> 
     <item>1</item> 
    </string-array>  
</resources> 

Những gì tôi mong đợi bằng cách mã Java sau đây để xây dựng một hoạt động ưu tiên hoàn thành, với hộp kiểm và tùy chọn danh sách, văn bản tóm tắt của tùy chọn danh sách có thể được cập nhật tự động, khi bao giờ tôi thực hiện lựa chọn. Văn bản tóm tắt sẽ chuyển đổi ở giữa Giá trị hiển thị 0Giá trị hiển thị 1.

public class Preferences extends PreferenceActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.preferences); 
    } 
} 

Tuy nhiên, tôi nhận ra văn bản tóm tắt cho tùy chọn danh sách sẽ không tự động cập nhật. Chỉ khi tôi thực hiện đánh dấu/bỏ chọn vào hộp kiểm, chỉ toàn bộ hoạt động sẽ bị vô hiệu và văn bản tóm tắt cho tùy chọn danh sách sẽ CHỈ được cập nhật.

Do đó, tôi phải sửa đổi mã của mình như sau, trông giống như cồng kềnh.

public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.preferences); 
     PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 

     // Cumbersome way to make sure list preference's summary text is being updated. 
     final String key = "yyyModePreference"; 
     ListPreference listPreference = (ListPreference)findPreference(key); 
     final String value = PreferenceManager.getDefaultSharedPreferences(this).getString(key, key); 
     final int index = listPreference.findIndexOfValue(value); 
     if (index >= 0) { 
      final String summary = (String)listPreference.getEntries()[index];   
      listPreference.setSummary(summary); 
     } 
    } 

    @Override 
    public void onSharedPreferenceChanged(SharedPreferences options, String key) { 
     // Cumbersome way to make sure list preference's summary text is being updated. 
     if (key.equals("yyyModePreference")) { 
      ListPreference listPreference = (ListPreference)findPreference(key); 
      final String value = options.getString(key, key); 
      final int index = listPreference.findIndexOfValue(value);    
      if (index >= 0) { 
       final String summary = (String)listPreference.getEntries()[index];   
       listPreference.setSummary(summary); 
      } 
     } 
    } 
} 

Đây có phải là cách chính xác không? Có cách nào đơn giản, để đảm bảo văn bản tóm tắt của ListPreference luôn được cập nhật tự động bất cứ khi nào có thay đổi trong lựa chọn.

+0

Cảm ơn bạn, tôi đã mất nhiều thời gian để tìm hiểu điều này. – Gerhard

+0

bản sao có thể có của [Thay đổi tóm tắt của một ListPreference với giá trị mới (Android)] (http://stackoverflow.com/questions/7017082/change-the-summary-of-a-listpreference-with-the-new- giá trị-android) – CAMOBAP

Trả lời

24

Đây là một lỗi đã tồn tại trên nền tảng trước khi KitKat (tức là android-4.4_r0.7), và nó được cố định bằng cách cam kết 94c02a1

Các giải pháp từ các tác phẩm @ilomambo, nhưng có thể không phải là tốt nhất . Tôi đọc qua nguồn của ListPreference và đưa ra giải pháp này:

Tệp: ListPreferenceCompat.java

package com.example.yourapplication; 

import android.content.Context; 
import android.os.Build; 
import android.preference.ListPreference; 
import android.text.TextUtils; 
import android.util.AttributeSet; 

public class ListPreferenceCompat extends ListPreference { 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    public ListPreferenceCompat(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public ListPreferenceCompat(Context context) { 
     super(context); 
    } 

    // NOTE: 
    // The framework forgot to call notifyChanged() in setValue() on previous versions of android. 
    // This bug has been fixed in android-4.4_r0.7. 
    // Commit: platform/frameworks/base/+/94c02a1a1a6d7e6900e5a459e9cc699b9510e5a2 
    // Time: Tue Jul 23 14:43:37 2013 -0700 
    // 
    // However on previous versions, we have to workaround it by ourselves. 
    @Override 
    public void setValue(String value) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      super.setValue(value); 
     } else { 
      String oldValue = getValue(); 
      super.setValue(value); 
      if (!TextUtils.equals(value, oldValue)) { 
       notifyChanged(); 
      } 
     } 
    } 
} 

Khi bạn cần sử dụng ListPreference bằng xml, chỉ cần thay thẻ thành com.example.yourapplication.ListPreferenceCompat.

Công trình này gọn gàng trên thiết bị Samsung S4 chạy Android 4.3 của tôi và bên trong một trong các ứng dụng sản xuất của tôi.

+0

Cảm ơn vì điều này, nó hoạt động hoàn hảo! –

+0

Cảm ơn, bạn đã tiết kiệm cho tôi rất nhiều công cụ nhàm chán !! –

6

Tôi đoán một số loại hình này của một lỗi kì lạ, bởi vì tôi đã thử nghiệm nó trên giả lập chạy Android 2.3.3 và nó đã không làm việc, nhưng khi tôi thử nghiệm nó trên 4.0.3 nó làm việc. Những gì tôi đã làm là android:summary="%s" trong xml cho ListPreference và đó là tất cả.

+1

nó không phải là một lỗi. đó là một tính năng được thêm vào ở cấp api 15 (hoặc có thể là 14). – Ran

+0

cảm ơn @Waqas vì đã chỉ ra điều này, một tuần trước, tôi googled một câu trả lời có liên quan nhiều hơn, nơi người nghe phải được đính kèm và tóm tắt được truy cập theo lập trình để làm điều tương tự. – sonjz

1

IMHO đó là lỗi. Các OnClickListener() được định nghĩa trong ListPreference.java#builder.setSingleChoiceItems() không gọi notifyChanged()

tôi tình cờ được mã hóa ListPreference riêng tôi dựa trên mã đó, và chạy trên cùng một vấn đề như OP, tôi đã thêm notifyChanged():

  ... 
      dialog.dismiss(); 
      notifyChanged(); // <<<<<<<<<< 
     } 
}); 

và bây giờ tóm tắt tùy chọn được cập nhật ngay sau khi tôi chọn nó. Nó không phụ thuộc vào phiên bản Android, ListPreference đã được mã hóa như thế này từ bao giờ hết.

Các vấn đề liên quan