2012-04-12 24 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> 

、ここでは、私は完全に好みの活動を構築するために、次のJavaコードを持つことで期待してどのような私の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> 

で持っていますチェックボックスとリストのプリファレンスで、リストのプリファレンスの要約テキストを自動的に更新することができます。これまで私は選択を行う。サマリーテキストはの間で切り替わります。表示値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

+0

[ListPreferenceの概要を新しい値で変更する(Android)](http://stackoverflow.com/questions/7017082/change-the-summary-of-a-listpreference-with-the-new-値 - アンドロイド) – CAMOBAP

答えて

24

これは前にキットカットのプラットフォームに存在していたバグ(すなわちアンドロイド-4.4_r0.7)であり、それは@ilomambo作品から94c02a1

ソリューションをコミットすることで固定されているが、最高のものではないかもしれません。私はListPreferenceのソースを読んで、この解決策を思いついた。

ファイル: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(); 
      } 
     } 
    } 
} 

あなたは、単にcom.example.yourapplication.ListPreferenceCompatにタグを置き換える、XMLでListPreferenceを使用する必要があります。

これは、Android 4.3を実行している私のSamsung S4デバイスと、本番アプリの1つの内部できれいに動作します。

+0

これはありがとう、それは完璧に動作します! –

+0

ありがとう、私は退屈なものをたくさん保存! –

6

私はAndroidの2.3.3を実行しているエミュレータ上でそれをテストしてみたし、それが動作しませんでしたが、私は4.0.3でそれをテストしたとき、それは働いていたので、私は、奇妙なバグのそのいくつかの種類を推測します。私がしたのはandroid:summary="%s"のXMLでListPreferenceです。

+1

これはバグではありません。それはAPIレベル15(または多分14)で追加された機能です。 – Ran

+0

これを指摘してくれた@Waqasに感謝します。一週間前に、リスナーを添付して、同じことを行うためにプログラムでアクセスするサマリーを追加する必要がありました。 – sonjz

1

IMHOバグです。 ListPreference.java#builder.setSingleChoiceItems()で定義されたonClickListenerは()私はそのコードに基づいて自分のListPreferenceをコーディングすることが起こる、とOPと同じ問題に出くわしましたnotifyChanged()

を呼び出すことはありません、私はnotifyChanged()を追加しました:

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

と今度は私が選んだのと同じ要領で要約が更新されます。 Androidのバージョンに依存していないので、これまで以上にListPreferenceがこのようにコード化されています。

関連する問題