【问题标题】:Android List Preferences: have summary as selected value?Android List Preferences:将摘要作为选定值?
【发布时间】:2011-01-28 00:12:06
【问题描述】:

我有一个 Preference 活动,它使用我的 XML 文件定义的 List Preferences。如何将列表活动的摘要设置为所选值?

【问题讨论】:

    标签: java android


    【解决方案1】:

    最简单的方法就是让 Android 为您完成。假设您希望摘要与所选值匹配,您可以使用 XML 或 Java 中的 setSummary 方法简单地 set the summary of the ListPreference to "%s"。例如:

    <ListPreference
        android:key="pref_list"
        android:title="A list of preferences"
        android:summary="%s"
        android:entries="@array/pref_list_entries"
        android:entryValues="@array/pref_list_entries_values"
        android:defaultValue="0" />
    

    Android 会将%s 替换为首选项的当前字符串值,如ListPreference 的选择器所示。当您进入活动时,列表的摘要也将被正确设置 - 您无需编写任何特殊代码来进行初始设置。

    also works 与AndroidX ListPreference

    在我发现这一点之前,我花了太多时间与SharedPreferences 听众混在一起。

    【讨论】:

    • 我知道!我喜欢那些优雅的解决方案。如此简单,但很难找到;)
    • 我不得不将此与手动更新相结合...因为值更改时摘要不会更新...
    • 优秀的答案。信不信由你,但这实际上已记录在案:developer.android.com/reference/android/preference/…
    • 您能否确认,"%s" 需要 API >= 11?在我的测试中,"%s" 不适用于 Gingerbread 和早期版本。
    • @BaptisteCandellier 感谢您的提醒。如果存在某些东西,Android 团队将弃用它。我添加了指向androidx 的链接。
    【解决方案2】:

    如此简单 - 只需将以下属性添加到您的 XML 定义中 -

    <ListPreference
    ...    
    app:useSimpleSummaryProvider="true"
    ...
    />
    

    【讨论】:

    • 我认为这应该被赞成,因为这似乎是 %s 的首选解决方案。至少根据我在 logcat 中收到的消息:“不再支持使用字符串格式标记设置摘要。您应该改用 SummaryProvider”。
    【解决方案3】:

    我认为您正在寻找的东西很简单,您可以想到,将以下代码行添加到您的 Preference 项目中:

    android:summary="%1$s"
    

    所以它看起来像这样:

    <ListPreference
                android:key="@string/pref_temp_key"
                android:title="@string/pref_temp_title"
                android:dialogTitle="@string/pref_temp_dialog_title"
                android:entries="@array/pref_tempUnit_entries"
                android:entryValues="@array/pref_tempUnit_entries"
                android:summary="%1$s"
                android:defaultValue="@string/pref_temp_default_value" />
    

    【讨论】:

      【解决方案4】:

      您可以使用OnPreferenceChangeListener 动态更改摘要。问题是它获得了选定的值(来自android:entryValues),而不是标题(android:entries)。在下面的代码中,我使用了toString(),但正确的解决方案是找到该值的标题。无论如何,这个想法是可行的:

      public class Preferences extends PreferenceActivity {
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              addPreferencesFromResource(R.xml.your_prefs);
      
              ListPreference listPreference = (ListPreference) findPreference("preference_key");
              if(listPreference.getValue()==null) {
                  // to ensure we don't get a null value
                  // set first value by default
                  listPreference.setValueIndex(0);
              }
              listPreference.setSummary(listPreference.getValue().toString());
              listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                  @Override
                  public boolean onPreferenceChange(Preference preference, Object newValue) {
                      preference.setSummary(newValue.toString());
                      return true;
                  }
              });
          }
      }
      

      【讨论】:

        【解决方案5】:

        我也想实现类似的东西,但https://stackoverflow.com/a/8155029/592025 的问题在于,它显示了我偏好的值(如 1、2 3 等)。我想显示对应于所选值的条目(人类可读的字符串)。

        所以我以这种方式改变了它,并按照我需要的方式工作。

        listPreference.setSummary(servicePreference.getEntry().toString());
        listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    // Set the value as the new value
                    listPreference.setValue(newValue.toString());
                    // Get the entry which corresponds to the current value and set as summary
                    preference.setSummary(listPreference.getEntry());
                    return false;
                }
            });
        

        诀窍是使用getEntry() 而不是getValue(),一旦值更改,显式设置值并回读条目。

        【讨论】:

          【解决方案6】:

          首先在 onCreate 中获取对 ListPreference 的引用。您可以使用 findPreference()。例如:

          ListPreference pref = (ListPreference) findPreference("thePreferencesKey");
          

          然后,当您第一次加载 Activity 时,无论何时更改首选项值,使用您想要获取 ListPreference 值的任何方法并设置摘要:

          pref.setSummary(theNewString);
          

          【讨论】:

            【解决方案7】:

            这是我正在使用的代码,它不会手动调用 setValue,因为我相信这已经在稍后阶段完成了。

            这是一个例子:

            @Override
            public boolean onPreferenceChange(Preference preference, Object value)
            {
                String textValue = value.toString();
            
                ListPreference listPreference = (ListPreference) preference;
                int index = listPreference.findIndexOfValue(textValue);
            
                CharSequence[] entries = listPreference.getEntries();
            
                preference.setSummary(
                            index >= 0
                                    ? entries[index]
                                    : null);
            
                return true;
            }
            

            【讨论】:

              【解决方案8】:

              这正是我所做的,而且效果很好。在 onSharedPreferenceChangeListener 中,我只检查正在更改的键,然后使用 if 语句将 ListPreferences 转换回人类可读的(条目而不是 entryValue)。很简单。

              public class MyPreferences extends PreferenceFragment implements OnSharedPreferenceChangeListener{
              
              public void onCreate(Bundle savedInstanceState){
                  super.onCreate(savedInstanceState);
                  addPreferencesFromResource(R.xml.preferences);
                  context = getActivity();
              
                  if (context == null){
                      Log.e("error","context is null");
                  }
              
                  prefs = PreferenceManager.getDefaultSharedPreferences(context);
                  myFrequencyList = (Preference)  findPreference("frequency_key");
                  prefs.registerOnSharedPreferenceChangeListener(this);
              
              }
              
              
              @Override
              public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
                      String key) {
              
                      if(key.equals("frequency_key")){
                              String freq = sharedPreferences.getString("frequency_key", "8k Hz");
                              if(freq.equals("8000")){
                                  freq = "8k Hz";
                              }
                              else if(freq.equals("16000")){
                                  freq = "16k Hz";
                              }
                              else if(freq.equals("22050")){
                                  freq = "22.05k Hz";
                              }
                              else if(freq.equals("44100")){
                                  freq = "44.1k Hz";
                              }
                              else if(freq.equals("48000")){
                                  freq = "48k Hz";
                              }
                              else{
                                  freq = "8k Hz";
                              }
                              myFrequencyList.setSummary(freq);
                      }
              

              xml 布局

               <ListPreference android:id="@+id/frequency_list"
                      android:key="frequency_key"
                      android:summary="8000"
                      android:title="Sample Rate"
                      android:defaultValue="8000"
                      android:dialogTitle="Larger sample rates create better sound quality but larger file sizes."
                      android:entries="@array/freq_titles"
                      android:entryValues="@array/freq_values"
                      />
              

              xml 数组

              <?xml version="1.0" encoding="utf-8"?>
              

              <string-array name="freq_titles">
                  <item>48k Hz</item>
                  <item>44.1k Hz</item>
                  <item>22.05k Hz</item>
                  <item>16k Hz</item>
                  <item>8k Hz</item>
              </string-array>
              
              <string-array name="freq_values">
                  <item>48000</item>
                  <item>44100</item>
                  <item>22050</item>
                  <item>16000</item>
                  <item>8000</item>
              </string-array>
              

              【讨论】:

              • 理想情况下,您应该动态阅读摘要,这样您就不必在两个地方跟踪它。
              【解决方案9】:

              这是 midhunhk 答案的扩展版本,它也解决了有用的“android:summary”字符串

                      // Retrieve & populate flash modes
                      List<String> flashmodes = params.getSupportedFlashModes();
                      if (flashmodes != null) {
                          final ListPreference lp = (ListPreference) findPreference("flash_list");
                          final String lp_basesummary = "Set the Flash mode. The default is 'auto'";
              
                          lp.setEntries(flashmodes.toArray(new CharSequence[flashmodes.size()]));
                          lp.setEntryValues(flashmodes.toArray(new CharSequence[flashmodes.size()]));
                          // If there's only one option, make it the default
                          if (flashmodes.size() == 1)
                              lp.setValueIndex(0);
              
                          lp.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");
              
                          lp.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
              
                              @Override
                              public boolean onPreferenceChange(Preference preference, Object newValue) {
                                  // Set the value as the new value
                                  lp.setValue(newValue.toString());
                                  // Get the entry which corresponds to the current value
                                  // and set as summary
                                  preference.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");
                                  return false;
                              }
                          });
                      } else {
                          // Remove the preference
                          ((PreferenceGroup) findPreference("camera_preference")).removePreference(findPreference("flash_list"));
                      }
              
                      // Retrieve & populate focus modes
                      List<String> focusmodes = params.getSupportedFocusModes();
                      if (focusmodes != null) {
                          final ListPreference lp = (ListPreference) findPreference("focus_mode_list");
                          final String lp_basesummary = "Set the Focus mode. The default is 'auto'";
              ...
              

              而且,为了清楚起见,android:summary 已从相关的 xml 中删除。

              【讨论】:

                【解决方案10】:

                这是处理用户选择后铃声偏好摘要更新的一种方法。

                    final SharedPreferences preference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                
                    final RingtonePreference rp_shuttle = (RingtonePreference) findPreference("shuttle_tone");
                    rp_shuttle.setSummary(RingtoneManager
                            .getRingtone(getApplicationContext(), Uri.parse(preference.getString("shuttle_tone", "DEFAULT_SOUND")))
                            .getTitle(this));
                
                    rp_shuttle.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                
                        public boolean onPreferenceChange(Preference mypreference, Object newValue) {
                            rp_shuttle.setSummary(RingtoneManager.getRingtone(getApplicationContext(), Uri.parse(newValue + ""))
                                    .getTitle(getApplicationContext()));
                
                            return true;
                        }
                    })
                

                【讨论】:

                  【解决方案11】:

                  您在 PreferenceActivity 上有一个方法 bindPreferenceSummaryToValue,

                  您可以像这样轻松地将摘要添加到列表中:

                  private static void bindPreferenceSummaryToValue(Preference preference) {
                      preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
                  
                      sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
                              PreferenceManager
                                      .getDefaultSharedPreferences(preference.getContext())
                                      .getString(preference.getKey(), ""));
                  }
                  

                  在您的 OnCreate 方法中,您可以像这样调用绑定函数:

                  bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_OF_THE_LIST)));
                  

                  您可以用同样的方式轻松添加其他摘要:

                  bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_1)));
                  bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_2)));
                  bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_3)));
                  

                  【讨论】:

                    【解决方案12】:

                    在 onCreatePreferences 下这样做::

                    SharedPreferences sharedPreferences =getPreferenceScreen().getSharedPreferences();
                    PreferenceScreen prefScreen = getPreferenceScreen();
                    int count = prefScreen.getPreferenceCount();
                    
                    for (int i = 0; i < count; i++) {
                      Preference p = prefScreen.getPreference(i);
                        if (p instanceof ListPreference) {
                           String value = sharedPreferences.getString(p.getKey(), "");
                           ListPreference listPreference = (ListPreference) preference;
                           int prefIndex = listPreference.findIndexOfValue(stringValue);
                           if (prefIndex >= 0) {
                                preference.setSummary(listPreference.getEntries()[prefIndex]);
                          }
                        }
                     }  
                    

                    【讨论】:

                      猜你喜欢
                      • 2016-05-26
                      • 2021-02-12
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-09-01
                      • 2010-10-06
                      • 1970-01-01
                      相关资源
                      最近更新 更多