2012-04-12 41 views
15

儘管正在記錄中,但通過使用"%s",我可以將選定的值顯示爲摘要,但它不會按預期工作。只要選擇發生變化,ListPreference的摘要文本就不會自動更新

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

我有以下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> 

,這裏是我的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> 

我具有下列Java代碼來構建一個完整的偏好活動的期望是什麼,帶有複選框和列表首選項時,列表首選項的摘要文本可以自動更新我曾經執行過選擇。摘要文本將在之間切換顯示值0顯示值1

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

但是,我意識到列表首選項的摘要文本不會自動更新。只有當我在複選框上執行勾選/取消勾選時,只有整個活動將失效,列表首選項的摘要文本將僅被更新。

因此,我不得不修改我的代碼如下,這看起來更繁瑣

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

這是正確的方法嗎?有沒有簡化的方法,以確保ListPreference的摘要文本總是在選擇發生變化時自動更新。

+0

謝謝,要花費很長時間才能弄清楚這一點。 – Gerhard 2012-09-24 19:27:29

+0

[用新值(Android)更改ListPreference的摘要](http://stackoverflow.com/questions/7017082/change-the-summary-of-a-listpreference-with-the-new-價值-Android) – CAMOBAP 2014-12-04 11:24:17

回答

24

這是之前奇巧(即Android的4.4_r0.7)存在的平臺上的一個錯誤,它是由固定的承諾94c02a1

從@ilomambo工程解決方案,但可能不是最好的之一。我通讀了ListPreference的來源,並提出了這個解決方案:

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

當你需要在XML中使用ListPreference,只需更換標籤com.example.yourapplication.ListPreferenceCompat

這適用於運行Android 4.3的我的三星S4設備,以及我的一款生產應用程序。

+0

謝謝你,它完美的作品! – 2015-03-20 14:13:29

+0

謝謝,你爲我節省了很多無聊的東西! – 2015-12-22 11:43:52

6

我猜它的某種奇怪的錯誤,因爲我已經測試了運行Android 2.3.3 模擬器並沒有工作,但是當我測試4.0.3它的工作。我做的是android:summary="%s" xml ListPreference就是這樣。

+1

這不是一個錯誤。這是一個在api level 15(或者14)中添加的功能。 – Ran 2012-07-02 21:02:28

+0

感謝@Waqas指出了這一點,一週前我搜索了一個更復雜的答案,其中必須連接一個監聽器,並以編程方式訪問摘要以執行相同的操作。 – sonjz 2013-09-09 19:06:57

1

恕我直言,這是一個錯誤。在ListPreference.java#builder.setSingleChoiceItems()定義不叫notifyChanged()

的onClickListener()我碰巧基於該代碼進行編碼我自己ListPreference,並且在同樣的問題,因爲OP跑了,我加notifyChanged()

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

和現在,首選項摘要會在我選擇它時立即更新。 它不依賴於Android版本,因此ListPreference自此以後一直編碼。

相關問題