기본 설정 요약에서 Android 기본 설정의 현재 값을 표시하려면 어떻게합니까?


457

이것은 매우 자주 나타납니다.

사용자가 Android 앱에서 환경 설정을 편집 할 때 Preference요약 에서 현재 설정된 환경 설정 값을 볼 수 있기를 바랍니다 .

예 : 메시지를 정리해야하는 일 수를 지정하는 "오래된 메시지 폐기"에 대한 환경 설정이있는 경우 에서 PreferenceActivity내가 볼 수있는 사용자를하고 싶습니다 :

"오래된 메시지 삭제" <-제목

" x 일 후 메시지 정리 " <- 요약 여기서 x 는 현재 기본 설정 값입니다.

추가 크레딧 : 재사용 할 수 있도록 유형에 관계없이 모든 기본 설정에 쉽게 적용 할 수 있습니다 (최소한의 코딩으로 EditTextPreference, ListPreference 등으로 작동하도록).

답변:


151

필요에 따라이 솔루션을보다 일반적인 솔루션으로 만드는 방법이 있습니다.

예를 들어, 일반적으로 모든 목록 환경 설정에 선택 사항이 요약으로 표시되도록하려면 onSharedPreferenceChanged구현에 이를 사용할 수 있습니다.

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    Preference pref = findPreference(key);

    if (pref instanceof ListPreference) {
        ListPreference listPref = (ListPreference) pref;
        pref.setSummary(listPref.getEntry());
    }
}

이것은 다른 환경 설정 클래스로 쉽게 확장 할 수 있습니다.

그리고 사용 getPreferenceCountgetPreference의 기능을 PreferenceScreen하고 PreferenceCategory, 당신은 쉽게 당신이 자신에게 원하는 종류의 모든 환경 설정의 요약 설정 설정 트리 걸어 일반적인 기능을 쓸 수있는 toString표현을


6
정말 좋은 해결책. 초기화 만 부족함
njzk2

9
@ njzk2 당신이해야 할 모든 활동을 확인하는 것입니다implements OnSharedPreferenceChangeListener

4
NB : 더 간단한 방법이 있습니다 . @Robertas의 답변을 참조하십시오 .
Salman von Abbas

6
사실, 당신이 요약을 설정할 수 있습니다 "%s"에 대한 ListPreference, 그리고 ListPreference.getSummary()현재 선택한 항목으로 요약을 포맷 (또는 ""아무 것도 선택하지 않은 경우).
SOFe

findPreference (key)는 더 이상 사용되지 않습니다. 이것에 액세스하는 다른 방법이 있습니까?
Nevermore

144

여기 내 해결책이 있습니다 ... FWIW

package com.example.PrefTest;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;

public class Preferences extends PreferenceActivity implements
        OnSharedPreferenceChangeListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        PreferenceManager.setDefaultValues(Preferences.this, R.xml.preferences,
            false);
        initSummary(getPreferenceScreen());
    }

    @Override
    protected void onResume() {
        super.onResume();
        // Set up a listener whenever a key changes
        getPreferenceScreen().getSharedPreferences()
                .registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Unregister the listener whenever a key changes
        getPreferenceScreen().getSharedPreferences()
                .unregisterOnSharedPreferenceChangeListener(this);
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
            String key) {
        updatePrefSummary(findPreference(key));
    }

    private void initSummary(Preference p) {
        if (p instanceof PreferenceGroup) {
            PreferenceGroup pGrp = (PreferenceGroup) p;
            for (int i = 0; i < pGrp.getPreferenceCount(); i++) {
                initSummary(pGrp.getPreference(i));
            }
        } else {
            updatePrefSummary(p);
        }
    }

    private void updatePrefSummary(Preference p) {
        if (p instanceof ListPreference) {
            ListPreference listPref = (ListPreference) p;
            p.setSummary(listPref.getEntry());
        }
        if (p instanceof EditTextPreference) {
            EditTextPreference editTextPref = (EditTextPreference) p;
            if (p.getTitle().toString().toLowerCase().contains("password"))
            {
                p.setSummary("******");
            } else {
                p.setSummary(editTextPref.getText());
            }
        }
        if (p instanceof MultiSelectListPreference) {
            EditTextPreference editTextPref = (EditTextPreference) p;
            p.setSummary(editTextPref.getText());
        }
    }
}

이것은 환경 설정 화면 내에 환경 설정 화면이 있다는 것을 제외하고는 @EddieB에서 훌륭하게 작동합니다. 내부 환경 설정 화면에 도달하여 요약으로 채우는 방법에 대한 아이디어가 있습니까?
taraloca

@taraloca-다음과 같은 경우 변경 (p instanceCategory의 p 인스턴스) {PreferenceCategory pCat = (PreferenceCategory) p; if (PreferenceGroup의 p instance) {final PreferenceGroup pCat = (PreferenceGroup) p;
Martin Ždila

경우에 무엇이 작동하고 좋은 EditTextPreference이다 android:password="true" 는 값을 보여줍니다
Chathura Wijesinghe

1
값이 정의되지 않은 경우 (예 :) 리소스 (xml) 파일에서 요약을 표시하도록 코드를 어떻게 수정해야 if editTextPref.getText() == ""합니까? 에서 요약 값을 얻는 방법은 updatePrefSummary무엇입니까? p.getSummary()그리고 editTextPref.getSummary()이미 수정 된 값을 반환합니다.
LA_

PreferenceCategory와에서 PreferenceScreen상속 받았 으므로 대신 처리하도록 PreferenceGroup변경되었습니다 . 이렇게하면에 다른 루프가 필요하지 않습니다 . 동작 변경 : 중첩 된 PreferenceScreen도 이제 재귀 적으로 처리됩니다. initSummaryPreferenceGrouponCreate()
Lekensteyn 2016 년

96

안드로이드 문서에 따르면 다음에서 문자열 형식 표시를 사용할 수 있습니다 getSummary().

요약에 문자열 형식 표시가있는 경우 (예 : "% s"또는 "% 1 $ s") 현재 입력 값이 대신 사용됩니다.

android:summary="Clean up messages after %s days"ListPreference xml 선언에 간단히 지정하면 나에게 도움이되었습니다.

참고 : 이 경우에만 작동합니다 ListPreference.


내가 틀렸다면 누군가 나를 수정하지만 getSummary ()에 대한 설명서에 API 레벨 1에 추가되었다고 명시되어 있습니다. 처음 릴리스했을 때 동작이 다르다는 것을 의미합니까?
TheIT 2016

10
불행히도 이것은 ListPreference에서만 작동합니다. EditTextPreference와 동일한 동작을 원합니다. Google이 모든 DialogPreferences에 이것을 추가하지 않은 것은 놀라운 일입니다.
Vicki

2
또한, 값이 설정되지 않은 한 작동하지 않습니다 .Preference 활동을 처음 호출 할 때 실제로 멍청한 % s 만 표시됩니다.
Zordid

3
@Zordid ListPreference에서와 같이 XML에 기본값을 지정 android:defaultValue="0"하여 해결할 수 있습니다. 이것은 가장 현명한 답변이며 저에게 효과적입니다.
Mohit Singh

@Mohit 싱 / @Zordid는 롤리팝 API (22)에, defaultValue그리고이 %s일을하지 않습니다. 다른 버전에서는 일반적으로 작동합니다. 어떤 해결책이 있습니까? 나는 이것을 위해 커스텀 클래스를 작성하고 싶지 않다. 구글이 가장 사소한 작업을 고통스럽게한다고 믿기지 않습니다.
Narayana J

81

를 사용 PreferenceFragment하면 이것이 해결 된 방법입니다. 자체 설명입니다.

public static class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      addPreferencesFromResource(R.xml.settings);
      getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onResume() {
      super.onResume();
      for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); ++i) {
        Preference preference = getPreferenceScreen().getPreference(i);
        if (preference instanceof PreferenceGroup) {
          PreferenceGroup preferenceGroup = (PreferenceGroup) preference;
          for (int j = 0; j < preferenceGroup.getPreferenceCount(); ++j) {
            Preference singlePref = preferenceGroup.getPreference(j);
            updatePreference(singlePref, singlePref.getKey());
          }
        } else {
          updatePreference(preference, preference.getKey());
        }
      }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
      updatePreference(findPreference(key), key);
    }

    private void updatePreference(Preference preference, String key) {
      if (preference == null) return;
      if (preference instanceof ListPreference) {
        ListPreference listPreference = (ListPreference) preference;
        listPreference.setSummary(listPreference.getEntry());
        return;
      }
      SharedPreferences sharedPrefs = getPreferenceManager().getSharedPreferences();
      preference.setSummary(sharedPrefs.getString(key, "Default"));
    }
  }

3
이 솔루션에는 더 많은 투표가 필요합니다 ... 개발자 사이트의 예제 에서이 작업을 수행하지만 완전히 생략한다는 버그가 있습니다.
Justin Smith

3
EditTextPreferences도 업데이트하려면 updatePreference코드 if (preference instanceof EditTextPreference) { EditTextPreference editTextPref = (EditTextPreference) preference; preference.setSummary(editTextPref.getText()); }에 이것을 추가하십시오. @EddieB
Eugene van der Merwe

6
어디로 전화 unregisterOnSharedPreferenceChangeListener해요?
CAMOBAP

1
findPreference(CharSequence key) This method was deprecated in API level 11. This function is not relevant for a modern fragment-based PreferenceActivity.
DSlomer64

2
@ DSlomer64 나는 당신이 인용하는 것을 잘 알고 있습니다. PreferenceActivity.findPreferenceGoogle 은이 답변에 표시된 기술로 전환하기를 원하기 때문에 (및 여러 가지 다른 방법) 사용하지 말라고 지시 하고 있습니다 PreferenceFragment.findPreference.
Dan Hulme

33

내 옵션은 ListPreference를 확장하는 것이며 깨끗합니다.

public class ListPreferenceShowSummary extends ListPreference {

    private final static String TAG = ListPreferenceShowSummary.class.getName();

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

    public ListPreferenceShowSummary(Context context) {
        super(context);
        init();
    }

    private void init() {

        setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

            @Override
            public boolean onPreferenceChange(Preference arg0, Object arg1) {
                arg0.setSummary(getEntry());
                return true;
            }
        });
    }

    @Override
    public CharSequence getSummary() {
        return super.getEntry();
    }
}

그런 다음 settings.xml에 추가하십시오.

<yourpackage.ListPreferenceShowSummary
    android:key="key" android:title="title"
    android:entries="@array/entries" android:entryValues="@array/values"
    android:defaultValue="first value"/>

이를 기반으로 솔루션을 만들었습니다. 내 솔루션에는 메뉴와 요약 모두에서 항목 문자열을 사용하는 대신 entrySummaries 배열을 설정하는 방법이 있습니다. 여기에는 한 가지 문제점이 있습니다. getEntry ()는 새로운 값이 아닌 이전 값을 리턴합니다.
pzulw February

1
실제로 init ()는 필요합니까? 방금 getSummary ()를 재정의했으며 정상적으로 작동하는 것 같습니다!
Andy

4
가장 많이 투표 된 것보다 훨씬 쉽고 깨끗한 솔루션 인 것 같습니다!
muslidrikk

2
사용자가 해당 환경 설정을 변경할 때 init()기능을 업데이트하려면 이 기능이 필요합니다 summary. 그것없이, 그것은 단지 항목이 처음 있던 그대로 유지됩니다.
anthonylawson

23

기본 환경 설정 클래스를 대체하고 기능을 구현할 수 있습니다.

public class MyListPreference extends ListPreference  {
    public MyListPreference(Context context) { super(context); }
    public MyListPreference(Context context, AttributeSet attrs) { super(context, attrs); }
    @Override
    public void setValue(String value) {
        super.setValue(value);
        setSummary(getEntry());
    }
}

나중에 당신은 XML과 같은 사용자 정의 환경 설정을 사용할 수 있습니다

<your.package.name.MyListPreference 
    android:key="noteInterval"
    android:defaultValue="60"
    android:title="Notification Interval"
    android:entries="@array/noteInterval"
    android:entryValues="@array/noteIntervalValues"
    />

훌륭한 간단한 방법. 문제를 일으킬 수있는 getEntry 문자열에 %와 같은 것들이 있는지주의하십시오.
Andrew

21

몇 시간 후 나는이 문제를 해결하기 위해이 코드를 구현했다.

[업데이트 : 최종 버전 목록]

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

        m_updateList = (ListPreference) findPreference(getString(R.string.pref_update_interval_key));
        String currentValue = m_updateList.getValue();
        if (currentValue == null) {
            m_updateList.setValue((String)m_updateList.getEntryValues()[DEFAULT_UPDATE_TIME_INDEX]);
            currentValue = m_updateList.getValue();
        }
        updateListSummary(currentValue);    

        m_updateList.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                updateListSummary(newValue.toString());
                return true;
            }       
        });     
    }

    private void updateListSummary(String newValue) {
        int index = m_updateList.findIndexOfValue(newValue);
        CharSequence entry = m_updateList.getEntries()[index];
        m_updateList.setSummary(entry);
    }
}

그것이 나를 위해 일한 유일한 해결책이었습니다. ListPreferences에서 서브 클래스를 만들고 android : summary = "bla bla bla % s"를 구현하기 전에. 둘 다 일하지 않았다.


당신의 방법은 더 명확하고 다른 코드보다 적은 코드를 사용합니다. 최고 답변은 "프록시"-환경 설정 관리자를 사용하여 작동합니다. 목록에서 직접 변경 사항을 듣는 것만 큼 명확하지 않습니다.
Paul Annekov

@ Subtle Fox, 깔끔한 솔루션. 'setDefaultValue ()'를했는지 궁금하다면 왜 (ss == null)을 확인해야
Samuel

setDefaultValue ()가 없어야하기 때문에 :) 리팩토링하기 전에이 코드를 넣었습니다.
Subtle Fox

20

아마도 ListPreference와 같이 : getSummary를 수정하여 원하는 것을 얻으십시오.

package your.package.preference;

import android.content.Context;
import android.util.AttributeSet;

public class EditTextPreference extends android.preference.EditTextPreference{
        public EditTextPreference(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

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

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

        @Override
        public CharSequence getSummary() {
            if(super.getSummary() == null) return null;

            String summary = super.getSummary().toString();
            return String.format(summary, getText());
        }
    }

그리고 이것을 XML에서 사용하십시오 :

<your.package.EditTextPreference
                android:key="pref_alpha"
                android:summary="Actual value: %s"
                android:title="Title"
                android:defaultValue="default"
                />

따라서 %s실제 값 대신 요약을 작성할 수 있습니다.


1
@Eruvanos @ serv-inc 최소한의 서브 클래스를 사용 android.support.v7.preference.EditTextPreference하면 환경 설정 활동이 작성 될 때만 환경 설정이 변경 될 때 요약이 업데이트되지 않습니다. OnSharedPreferenceChangeListener.onSharedPreferenceChanged환경 설정 프래그먼트 클래스에서 구현하지 않고이 문제를 해결하는 방법은 다음을 재정의하는 것입니다 android.support.v7.preference.EditTextPreference.setText(String text).@Override public void setText(String text) { super.setText(text); this.setSummary(this.getText()); }
PointedEars

@PointedEars : 완료 그러나 이것은 또한 stackoverflow.com/a/21906829/1587329
serv-inc

18

이것은 요약을 선택한 값으로 설정하는 데 필요한 코드입니다. 또한 시작시 값을 설정하고 변경시뿐만 아니라 기본값도 준수합니다. "R.layout.prefs"를 xml 파일로 변경하고 setSummary-method를 필요에 맞게 확장하십시오. 실제로는 ListPreferences 만 처리하지만 다른 기본 설정을 준수하도록 쉽게 사용자 정의 할 수 있습니다.

package de.koem.timetunnel;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;

public class Prefs 
    extends PreferenceActivity 
    implements OnSharedPreferenceChangeListener {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       this.addPreferencesFromResource(R.layout.prefs);
       this.initSummaries(this.getPreferenceScreen());

       this.getPreferenceScreen().getSharedPreferences()
           .registerOnSharedPreferenceChangeListener(this);
    }

  /**
    * Set the summaries of all preferences
    */
  private void initSummaries(PreferenceGroup pg) {
      for (int i = 0; i < pg.getPreferenceCount(); ++i) {
          Preference p = pg.getPreference(i);
          if (p instanceof PreferenceGroup)
              this.initSummaries((PreferenceGroup) p); // recursion
          else
              this.setSummary(p);
      }
  }

  /**
    * Set the summaries of the given preference
    */
  private void setSummary(Preference pref) {
      // react on type or key
      if (pref instanceof ListPreference) {
          ListPreference listPref = (ListPreference) pref;
          pref.setSummary(listPref.getEntry());
      }
  }

  /**
    * used to change the summary of a preference
    */
  public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
     Preference pref = findPreference(key);
     this.setSummary(pref);
  }

  // private static final String LOGTAG = "Prefs";
}

em


고마워요! 이 클래스에서 리소스 ID를 onCreate ()에 대한 인수로 제공하여 클래스를 만들었습니다. 이렇게하면 설정 화면을 한 줄로 변경하여 값을 요약하여 표시했습니다.
Asmo Soinio 2012

2
BTW : 비 지속적 환경 설정은이 시스템을 사용하여 업데이트되지 않습니다. setOnPreferenceChangeListener(Preference.OnPreferenceChangeListener onPreferenceChangeListener)개별 환경 설정 의 -method를 사용하여 변경 사항을 청취해야합니다 .
Asmo Soinio

11

실제로 CheckBoxPreference 에는 확인란 값을 기반으로 다른 요약을 지정할 수있는 기능이 있습니다. android : summaryOff 및 android : summaryOn 속성 및 해당 CheckBoxPreference 메소드를 참조하십시오.


11

EditTextPreference의 경우 :

public class MyEditTextPreference extends EditTextPreference {
    public MyEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

    @Override
    public void setText(String text) {
        super.setText(text);
        setSummary(text);
    }
}

9

누군가 여전히 이것에 대한 답을 찾고 있다면, thirtythreeforty 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는 ListPreference의 선택 도구에 표시된대로 % s를 기본 설정의 현재 문자열 값으로 바꿉니다.


공장. 이것이 오늘날 가장 쉽고 최고의 솔루션입니다.
davidgyoung

1
"% s"는 요약 문자열의 어느 곳에 나 배치 할 수 있습니다. 그리고 네, 여기에는 리소스 문자열이 포함됩니다!
Scott Biggs

7

이 팁에 감사드립니다!

하나의 환경 설정 화면이 있고 각 목록 환경 설정의 값을 요약으로 표시하고 싶습니다.

이것은 지금 내 길입니다.

public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
}

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

    // Set up initial values for all list preferences
    Map<String, ?> sharedPreferencesMap = getPreferenceScreen().getSharedPreferences().getAll();
    Preference pref;
    ListPreference listPref;
    for (Map.Entry<String, ?> entry : sharedPreferencesMap.entrySet()) {
        pref = findPreference(entry.getKey());
        if (pref instanceof ListPreference) {
            listPref = (ListPreference) pref;
            pref.setSummary(listPref.getEntry());
        }
    }

    // Set up a listener whenever a key changes            
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onPause() {
    super.onPause();

    // Unregister the listener whenever a key changes            
    getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);    
}

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    Preference pref = findPreference(key);

    if (pref instanceof ListPreference) {
        ListPreference listPref = (ListPreference) pref;
        pref.setSummary(listPref.getEntry());
    }
}

이것은 나를 위해 작동하지만 Koem이 보여주는 것이 가장 좋은 해결책 (성능, 안정성, 확장 성)이 무엇인지 궁금합니다.


6

자세한 설명을 위해 Reto에게 감사합니다!

이것이 누군가에게 도움이되는 경우 Reto Meier가 제안한 코드를 변경하여 Android 1.5 용 SDK에서 작동하도록해야했습니다.

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

    // Setup the initial values
    mListPreference.setSummary("Current value is " + mListPreference.getEntry().toString()); 

    // Set up a listener whenever a key changes            
    ...
}

콜백 함수에도 동일한 변경 사항이 적용됩니다 onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)

건배,

크리스


4

ListPreference의 다음 자손으로 문제를 해결했습니다.

public class EnumPreference extends ListPreference {

    public EnumPreference(Context aContext, AttributeSet attrs) {
        super(aContext,attrs);
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
        setSummary(getEntry());
        return super.onCreateView(parent);
    }

    @Override
    protected boolean persistString(String aNewValue) {
        if (super.persistString(aNewValue)) {
            setSummary(getEntry());
            notifyChanged();
            return true;
        } else {
            return false;
        }
    }
}

1.6에서 4.0.4까지 나에게 잘 작동하는 것 같습니다.


4
public class ProfileManagement extends PreferenceActivity implements
OnPreferenceChangeListener {
    EditTextPreference screenName;
    ListPreference sex;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.layout.profile_management);

            screenName = (EditTextPreference) findPreference("editTextPref");
            sex = (ListPreference) findPreference("sexSelector");

            screenName.setOnPreferenceChangeListener(this);
            sex.setOnPreferenceChangeListener(this);

    }   

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        preference.setSummary(newValue.toString());
        return true;
    }
}

4

모든 투표 답변에서 정확한 현재 값으로 요약을 설정하는 방법을 보여 주었지만 OP는 다음과 같은 것을 원했습니다.

" x 일 후 메시지 정리 "* <-요약 여기서 x 는 현재 기본 설정 값입니다.

그것을 달성하기위한 나의 대답은 다음과 같습니다.

문서 에 대해 말한다 ListPreference.getSummary():

이 ListPreference의 요약을 돌려줍니다. 요약에 문자열 형식 표시가있는 경우 (예 : "% s"또는 "% 1 $ s") 현재 입력 값이 대신 사용됩니다.

그러나 여러 장치에서 시도했지만 작동하지 않는 것 같습니다. 약간의 연구를 통해이 답변 에서 좋은 해결책을 찾았습니다 . Android 문서에서 지정한대로 작동 Preference하고 재정의 getSummary()할 때마다 확장하는 것만으로 구성됩니다 .


1
처음에는 작동하는 것처럼 보이지만 새 값을 선택하면 전체 활동을 무효화하고 다시 그리기 위해 무언가를 할 때까지 자동으로 업데이트되지 않습니다. 나는 안드로이드 4.0.4에 있습니다.
eidylon

Google이 환경 설정 객체에 서식 문자열을 추가 할 수 있다면 좋을 것입니다.
Justin Smith

3

각 필드의 일반 텍스트 값만 요약으로 표시하려면 다음 코드를 유지 관리하는 것이 가장 쉬워야합니다. 두 가지 변경 만 필요합니다 ( "여기에서 변경"으로 표시된 13 행 및 21 행) :

package com.my.package;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;

public class PreferencesActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {

    private final String[] mAutoSummaryFields = { "pref_key1", "pref_key2", "pref_key3" }; // change here
    private final int mEntryCount = mAutoSummaryFields.length;
    private Preference[] mPreferenceEntries;

    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences_file); // change here
        mPreferenceEntries = new Preference[mEntryCount];
        for (int i = 0; i < mEntryCount; i++) {
            mPreferenceEntries[i] = getPreferenceScreen().findPreference(mAutoSummaryFields[i]);
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void onResume() {
        super.onResume();
        for (int i = 0; i < mEntryCount; i++) {
            updateSummary(mAutoSummaryFields[i]); // initialization
        }
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); // register change listener
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); // unregister change listener
    }

    private void updateSummary(String key) {
        for (int i = 0; i < mEntryCount; i++) {
            if (key.equals(mAutoSummaryFields[i])) {
                if (mPreferenceEntries[i] instanceof EditTextPreference) {
                    final EditTextPreference currentPreference = (EditTextPreference) mPreferenceEntries[i];
                    mPreferenceEntries[i].setSummary(currentPreference.getText());
                }
                else if (mPreferenceEntries[i] instanceof ListPreference) {
                    final ListPreference currentPreference = (ListPreference) mPreferenceEntries[i];
                    mPreferenceEntries[i].setSummary(currentPreference.getEntry());
                }
                break;
            }
        }
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        updateSummary(key);
    }

}

3

내 해결책은 다음과 같습니다.

환경 설정 유형 'getter'메소드를 빌드하십시오.

protected String getPreference(Preference x) {
    // http://stackoverflow.com/questions/3993982/how-to-check-type-of-variable-in-java
    if (x instanceof CheckBoxPreference)
        return "CheckBoxPreference";
    else if (x instanceof EditTextPreference)
        return "EditTextPreference";
    else if (x instanceof ListPreference)
        return "ListPreference";
    else if (x instanceof MultiSelectListPreference)
        return "MultiSelectListPreference";
    else if (x instanceof RingtonePreference)
        return "RingtonePreference";
    else if (x instanceof SwitchPreference)
        return "SwitchPreference";
    else if (x instanceof TwoStatePreference)
        return "TwoStatePreference";
    else if (x instanceof DialogPreference) // Needs to be after ListPreference
        return "DialogPreference";
    else
        return "undefined";
}

'setSummaryInit'메소드를 빌드하십시오.

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        Log.i(TAG, "+ onSharedPreferenceChanged(prefs:" + prefs + ", key:" + key + ")");
        if( key != null ) {
            updatePreference(prefs, key);
            setSummary(key);
        } else {
            Log.e(TAG, "Preference without key!");
        }
        Log.i(TAG, "- onSharedPreferenceChanged()");
    }

    protected boolean setSummary() {
        return _setSummary(null);
    }

    protected boolean setSummary(String sKey) {
        return _setSummary(sKey);
    }

    private boolean _setSummary(String sKey) {
        if (sKey == null) Log.i(TAG, "Initializing");
        else Log.i(TAG, sKey);

        // Get Preferences
        SharedPreferences sharedPrefs = PreferenceManager
                .getDefaultSharedPreferences(this);

        // Iterate through all Shared Preferences
        // http://stackoverflow.com/questions/9310479/how-to-iterate-through-all-keys-of-shared-preferences
        Map<String, ?> keys = sharedPrefs.getAll();
        for (Map.Entry<String, ?> entry : keys.entrySet()) {
            String key = entry.getKey();
            // Do work only if initializing (null) or updating specific preference key
            if ( (sKey == null) || (sKey.equals(key)) ) {
                String value = entry.getValue().toString();
                Preference pref = findPreference(key);
                String preference = getPreference(pref);
                Log.d("map values", key + " | " + value + " | " + preference);
                pref.setSummary(key + " | " + value + " | " + preference);
                if (sKey != null) return true;
            }
        }
        return false;
    }

    private void updatePreference(SharedPreferences prefs, String key) {
        Log.i(TAG, "+ updatePreference(prefs:" + prefs + ", key:" + key + ")");
        Preference pref = findPreference(key);
        String preferenceType = getPreference(pref);
        Log.i(TAG, "preferenceType = " + preferenceType);
        Log.i(TAG, "- updatePreference()");
    }

초기화

PreferenceActivity가 공용 클래스를 작성하고 OnSharedPreferenceChangeListener를 구현하십시오.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    PreferenceManager.setDefaultValues(this, R.xml.global_preferences,
    false);
    this.addPreferencesFromResource(R.xml.global_preferences);
    this.getPreferenceScreen().getSharedPreferences()
        .registerOnSharedPreferenceChangeListener(this);
}

protected void onResume() {
    super.onResume();
    setSummary();
}


3

참고 사항 :

findPreference(CharSequence key)
This method was deprecated in API level 11. This function is not relevant
for a modern fragment-based PreferenceActivity.

아주 매끄러운 보는 모든 이유가 더 Answer이상 @ASD의 ( 소스는 여기에서 찾을 사용하는 말) %s에서 android:summary의 각 필드에 대해 preferences.xml. (현재 선호하는 값이 대신 사용됩니다 %s.)

여기에 이미지 설명을 입력하십시오

<ListPreference
 ...        
 android:summary="Length of longest word to return as match is %s"
 ...
 />

3

androidx Preference 클래스에는 SummaryProvider 인터페이스가 있으므로 OnSharedPreferenceChangeListener없이 수행 할 수 있습니다. EditTextPreference 및 ListPreference에 대한 간단한 구현이 제공됩니다. EddieB의 답변바탕으로 다음과 같이 보일 수 있습니다. androidx.preference : preference : 1.1.0-alpha03에서 테스트되었습니다.

package com.example.util.timereminder.ui.prefs;

import android.os.Bundle;

import com.example.util.timereminder.R;

import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;

/**
 * Displays different preferences.
 */
public class PrefsFragmentExample extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.preferences);

        initSummary(getPreferenceScreen());
    }

    /**
     * Walks through all preferences.
     *
     * @param p The starting preference to search from.
     */
    private void initSummary(Preference p) {
        if (p instanceof PreferenceGroup) {
            PreferenceGroup pGrp = (PreferenceGroup) p;
            for (int i = 0; i < pGrp.getPreferenceCount(); i++) {
                initSummary(pGrp.getPreference(i));
            }
        } else {
            setPreferenceSummary(p);
        }
    }

    /**
     * Sets up summary providers for the preferences.
     *
     * @param p The preference to set up summary provider.
     */
    private void setPreferenceSummary(Preference p) {
        // No need to set up preference summaries for checkbox preferences because
        // they can be set up in xml using summaryOff and summary On
        if (p instanceof ListPreference) {
            p.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
        } else if (p instanceof EditTextPreference) {
            p.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());
        }
    }
}

3

Android 문서 에 따르면 app:useSimpleSummaryProvider="true"ListPreference 및 EditTextPreference 구성 요소에서 사용할 수 있습니다 .


2

여기,이 모든 것은 Eclipse 샘플에서 잘립니다. SettingsActivity 냅니다. 이 안드로이드 개발자가 더 일반적이고 안정적인 코딩 스타일을 위해 완벽하게 선택하는 방법을 보여주기 위해 너무 많은 코드를 복사해야합니다.

PreferenceActivity태블릿 및 더 큰 API 에 맞게 코드를 남겼습니다 .

public class SettingsActivity extends PreferenceActivity {

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);

    setupSummaryUpdatablePreferencesScreen();
}

private void setupSummaryUpdatablePreferencesScreen() {

    // In the simplified UI, fragments are not used at all and we instead
    // use the older PreferenceActivity APIs.

    // Add 'general' preferences.
    addPreferencesFromResource(R.xml.pref_general);

    // Bind the summaries of EditText/List/Dialog preferences to
    // their values. When their values change, their summaries are updated
    // to reflect the new value, per the Android Design guidelines.
    bindPreferenceSummaryToValue(findPreference("example_text"));
    bindPreferenceSummaryToValue(findPreference("example_list"));
}

/**
 * A preference value change listener that updates the preference's summary
 * to reflect its new value.
 */
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {

    private String TAG = SettingsActivity.class.getSimpleName();

    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {
        String stringValue = value.toString();

        if (preference instanceof ListPreference) {
            // For list preferences, look up the correct display value in
            // the preference's 'entries' list.
            ListPreference listPreference = (ListPreference) preference;
            int index = listPreference.findIndexOfValue(stringValue);

            // Set the summary to reflect the new value.
            preference.setSummary(
                index >= 0
                ? listPreference.getEntries()[index]
                : null);
        } else {
            // For all other preferences, set the summary to the value's
            // simple string representation.
            preference.setSummary(stringValue);
        }
        Log.i(TAG, "pref changed : " + preference.getKey() + " " + value);
        return true;
    }
};

/**
 * Binds a preference's summary to its value. More specifically, when the
 * preference's value is changed, its summary (line of text below the
 * preference title) is updated to reflect the value. The summary is also
 * immediately updated upon calling this method. The exact display format is
 * dependent on the type of preference.
 *
 * @see #sBindPreferenceSummaryToValueListener
 */

private static void bindPreferenceSummaryToValue(Preference preference) {
    // Set the listener to watch for value changes.
    preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);

    // Trigger the listener immediately with the preference's
    // current value.
    sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
                                                             PreferenceManager
                                                             .getDefaultSharedPreferences(preference.getContext())
                                                             .getString(preference.getKey(), ""));
}

}

xml/pref_general.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

<!-- NOTE: EditTextPreference accepts EditText attributes. -->
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. -->
<EditTextPreference
android:capitalize="words"
android:defaultValue="@string/pref_default_display_name"
android:inputType="textCapWords"
android:key="example_text"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/pref_title_display_name" />

<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog todismiss it.-->
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
<ListPreference
android:defaultValue="-1"
android:entries="@array/pref_example_list_titles"
android:entryValues="@array/pref_example_list_values"
android:key="example_list"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/pref_title_add_friends_to_messages" />

</PreferenceScreen>

values/strings_activity_settings.xml

<resources>
<!-- Strings related to Settings -->

<!-- Example General settings -->

<string name="pref_title_display_name">Display name</string>
<string name="pref_default_display_name">John Smith</string>

<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
<string-array name="pref_example_list_titles">
<item>Always</item>
<item>When possible</item>
<item>Never</item>
</string-array>
<string-array name="pref_example_list_values">
<item>1</item>
<item>0</item>
<item>-1</item>
</string-array>
</resources>

노트: 실제로 "PreferenceActivity에 대한 Google의 샘플도 흥미 롭습니다."와 같이 설명하고 싶습니다. 하지만 평판이 충분하지 않아서 나를 비난하지 마십시오.

(영어가 안 좋아서 죄송합니다)


2

onCreate 메소드에서 bindPreferenceSummaryToValue 함수를 사용해야합니다.

예:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Add 'general' preferences, defined in the XML file
        addPreferencesFromResource(R.xml.pref_general);

        // For all preferences, attach an OnPreferenceChangeListener so the UI summary can be
        // updated when the preference changes.
        bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));
        bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_units_key)));
    }

Udacity Android 코스의 강의 3 참조 : https://www.udacity.com/course/viewer#!/c-ud853/l-1474559101/e-1643578599/m-1643578601


2

대한 EditTextPreference :

물론 특정 edittextpreference가 필요하지만 모든 환경 설정 에서이 작업을 수행 할 수 있다면이 솔루션에 왔습니다.

............

private static final String KEY_EDIT_TEXT_PREFERENCE2 = "on_a1";
public static  String value = "";

............

private void updatePreference(Preference preference, String key) {

            if (key.equals(KEY_EDIT_TEXT_PREFERENCE2)) {
                preference = findPreference(key);
                if (preference instanceof EditTextPreference) {
                    editTextPreference = (EditTextPreference) preference;
                    editTextPreference.setSummary(editTextPreference.getText());
                    value = editTextPreference.getText().toString();
                    return;
                }
                SharedPreferences sharedPrefs = getPreferenceManager().getSharedPreferences();
                preference.setSummary(sharedPrefs.getString(KEY_EDIT_TEXT_PREFERENCE2, ""));

            }
}

그런 다음 onResume ();

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

            SharedPreferences etext = getPreferenceManager().getSharedPreferences();
            String str = etext.getString("value", "");
            editTextPreference = (EditTextPreference) findPreference(KEY_EDIT_TEXT_PREFERENCE2);
            editTextPreference.setText(str);
            editTextPreference.setSummary(editTextPreference.getText());

            getPreferenceScreen().getSharedPreferences()
                    .registerOnSharedPreferenceChangeListener(this);
        }

에:

@Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            updatePreference(findPreference(key), key);
}

2

내 솔루션은 EditTextPreference다음과 같이 XML에서 사용되는 사용자 정의를 만드는 것입니다.<com.example.EditTextPreference android:title="Example Title" />

EditTextPreference.java :-

package com.example;

import android.content.Context;
import android.util.AttributeSet;

public class EditTextPreference extends android.preference.EditTextPreference
{
    public EditTextPreference(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

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

    public EditTextPreference(Context context)
    {
        super(context, null);
    }

    @Override
    protected void onDialogClosed(boolean positiveResult)
    {
        super.onDialogClosed(positiveResult);

        setSummary(getSummary());
    }

    @Override
    public CharSequence getSummary()
    {
        return getText();
    }
}

1

a의 요약을 ListPreference대화 상자에서 선택한 값으로 설정하려면 다음 코드를 사용할 수 있습니다.

package yourpackage;

import android.content.Context;
import android.util.AttributeSet;

public class ListPreference extends android.preference.ListPreference {

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

    protected void onDialogClosed(boolean positiveResult) {
        super.onDialogClosed(positiveResult);
        if (positiveResult) setSummary(getEntry());
    }

    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
        super.onSetInitialValue(restoreValue, defaultValue);
        setSummary(getEntry());
    }
}

호출을 트리거 할 yourpackage.ListPreferencepreferences.xml기억할 객체를 참조하여 지정 android:defaultValue합니다 onSetInitialValue().

원하는 경우 setSummary()응용 프로그램에 맞는 것을 호출 하기 전에 텍스트를 수정할 수 있습니다 .


1

나는 custom을 사용하고 있기 때문에 PreferenceDataStore일부에 리스너를 추가 할 수 없으므로 SharedPreference각 환경 설정을 수신하는 다소 해키 솔루션을 작성해야했습니다.

class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener {
    private val handler: Handler by lazy { Handler(Looper.getMainLooper()) }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        preferenceManager.preferenceDataStore = prefs
        addPreferencesFromResource(R.xml.app_preferences)
        onPreferenceChange(preferenceScreen, null)
    }

    override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
        preference.onPreferenceChangeListener = this

        when (preference) {
            is PreferenceGroup -> for (i in 0 until preference.preferenceCount) {
                onPreferenceChange(preference.getPreference(i), null)
            }
            is ListPreference -> {
                if (preference.value == null) {
                    preference.isPersistent = false
                    preference.value = Preference::class.java.getDeclaredField("mDefaultValue")
                            .apply { isAccessible = true }
                            .get(preference).toString()
                    preference.isPersistent = true
                }

                postPreferenceUpdate(Runnable { preference.summary = preference.entry })
            }
        }
        return true
    }

    /**
     * We can't directly update the preference summary update because [onPreferenceChange]'s result
     * is used to decide whether or not to update the pref value.
     */
    private fun postPreferenceUpdate(r: Runnable) = handler.post(r)
}

1

AndroidX를 사용하는 경우 custom을 사용할SummaryProvider있습니다 . 이 방법은 모든 용도로 사용할 수 있습니다 Preference.

문서의 예 (자바) :

EditTextPreference countingPreference = (EditTextPreference) findPreference("counting");

countingPreference.setSummaryProvider(new SummaryProvider<EditTextPreference>() {
    @Override
    public CharSequence provideSummary(EditTextPreference preference) {
        String text = preference.getText();
        if (TextUtils.isEmpty(text)){
            return "Not set";
        }
        return "Length of saved value: " + text.length();
    }
});

문서의 예 (Kotlin) :

val countingPreference = findPreference("counting") as EditTextPreference

countingPreference.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
    val text = preference.text
    if (TextUtils.isEmpty(text)) {
        "Not set"
    } else {
        "Length of saved value: " + text.length
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.