ฉันจะแสดงค่าปัจจุบันของการตั้งค่า 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());
    }
}

สิ่งนี้สามารถขยายได้อย่างง่ายดายสำหรับคลาสการกำหนดค่าตามความชอบอื่น

และด้วยการใช้ฟังก์ชั่นgetPreferenceCountและgetPreferenceในPreferenceScreenและPreferenceCategoryคุณสามารถเขียนฟังก์ชั่นทั่วไปเพื่อเดินแผนผังต้นไม้การตั้งค่าบทสรุปของการตั้งค่าทั้งหมดของประเภทที่คุณต้องการเพื่อtoStringเป็นตัวแทนของพวกเขา


6
ทางออกที่ดีแน่นอน ขาดการเริ่มต้นเท่านั้น
njzk2

9
@ njzk2 สิ่งที่คุณต้องทำคือให้แน่ใจว่ากิจกรรมimplements OnSharedPreferenceChangeListener

4
หมายเหตุ: มีวิธีที่ง่ายคือให้ดู@ คำตอบของ
Salman von Abbas

6
ที่จริงแล้วคุณสามารถตั้งค่าการสรุป"%s"สำหรับการListPreferenceและListPreference.getSummary()รูปแบบจะสรุปกับรายการที่เลือกในปัจจุบัน (หรือ""ถ้าไม่มีรายการที่เลือก)
SOFe

findPreference (คีย์) เลิกใช้แล้วมีวิธีอื่นในการเข้าถึงนี้หรือไม่
อีกแล้ว

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 - เปลี่ยน if (p instanceof PreferenceCategory) {PreferenceCategory pCat = (PreferenceCategory) p; ถึงถ้า (p instanceof PreferenceGroup) {final PreferenceGroup pCat = (PreferenceGroup) p;
Martin Ždila

นี้คือการทำงานที่ดีสิ่งที่ถ้าEditTextPreferenceเป็นandroid:password="true" มันแสดงให้เห็นค่า
Chathura Wijesinghe

1
ฉันจะแก้ไขโค้ดเพื่อแสดงข้อมูลสรุปจากไฟล์ resource (xml) ได้อย่างไรหากไม่มีการกำหนดค่า (เช่นif editTextPref.getText() == "") จะรับค่าสรุปได้updatePrefSummaryอย่างไร p.getSummary()และeditTextPref.getSummary()คืนค่าที่แก้ไขแล้ว
LA_

เนื่องจากทั้งคู่PreferenceCategoryและPreferenceScreenสืบทอดมาจากPreferenceGroupฉันเปลี่ยนinitSummaryไปจัดการPreferenceGroupแทน onCreate()นี้หลีกเลี่ยงความจำเป็นของวงอื่นใน การเปลี่ยนแปลงพฤติกรรม: PreferenceScreens ที่ซ้อนกันในขณะนี้ยังจัดการ ge แบบเรียกซ้ำ
Lekensteyn

96

เอกสาร Android กล่าวว่าหนึ่งสามารถใช้เครื่องหมายการจัดรูปแบบสตริงในgetSummary():

หากข้อมูลสรุปมีเครื่องหมายการจัดรูปแบบสตริงในนั้น (เช่น "% s" หรือ "% 1 $ s") ค่ารายการปัจจุบันจะถูกแทนที่ในตำแหน่งนั้น

เพียงแค่ระบุandroid:summary="Clean up messages after %s days"ในการประกาศ ListPreference xml ทำงานให้ฉัน

หมายเหตุ:ListPreferenceนี้จะทำงานเฉพาะสำหรับ


มีคนแก้ไขฉันถ้าฉันผิด แต่เอกสารสำหรับ getSummary () ระบุว่ามันถูกเพิ่มในระดับ API 1 คุณหมายถึงพฤติกรรมที่แตกต่างเมื่อเปิดตัวครั้งแรกหรือไม่?
TheIT

10
น่าเสียดายนี่ใช้งานได้กับ ListPreference เท่านั้น ฉันต้องการพฤติกรรมเดียวกันสำหรับ EditTextPreference เป็นเรื่องน่าแปลกใจที่ Google ไม่ได้เพิ่มสิ่งนี้สำหรับ DialogPreferences ทั้งหมด
วิคกี้

2
นอกจากนี้ฉันไม่ทำงานตราบใดที่ยังไม่ได้ตั้งค่า - ในการโทรครั้งแรกของกิจกรรมการตั้งค่าจะแสดงเพียง% s ซึ่งเป็นใบ้จริง ๆ
Zordid

3
@ Zordid ที่สามารถแก้ไขได้โดยการระบุค่าเริ่มต้นใน xml ของคุณเหมือนandroid:defaultValue="0"ใน ListPreference นี่คือคำตอบที่สมเหตุสมผลที่สุดและเหมาะกับฉัน
Mohit Singh

@Mohit Singh / @Zordid บน Lollipop API 22 defaultValueและ the %sไม่ทำงาน ในรุ่นอื่น ๆ โดยทั่วไปมันใช้งานได้ โปรดแก้ปัญหาใด ๆ ฉันแน่ใจว่าไม่ต้องการเขียนคลาสแบบกำหนดเองสำหรับสิ่งนี้ ไม่น่าเชื่อว่า Google จะทำสิ่งเล็ก ๆ น้อย ๆ ให้เจ็บปวดที่สุด
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 อัปเดตแล้วให้เพิ่มไปยังupdatePreferenceCODE 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.findPreference(และวิธีอื่น ๆ ) เพราะ Google ต้องการให้คุณเปลี่ยนไปใช้เทคนิคที่แสดงในคำตอบนี้ซึ่งใช้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"/>

ฉันทำทางออกจากสิ่งนี้ ในโซลูชันของฉันฉันมีวิธีการตั้งค่าอาร์เรย์ของรายการแทนการใช้สตริงรายการในทั้งเมนูและสรุป มีปัญหาหนึ่งที่นี่: getEntry () คืนค่าก่อนหน้าไม่ใช่ค่าใหม่
pzulw

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 ขณะที่พวกเขาอาจจะก่อให้เกิดปัญหา (หรือที่พวกเขาได้สำหรับฉัน)
แอนดรู

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

นั่นเป็นทางออกเดียวที่ทำงานได้ดีสำหรับฉัน ก่อนที่ฉันจะพยายาม subclass จาก 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: เสร็จแล้ว แต่นี่ก็น่าจะเป็นสำเนาของstackoverflow.com/a/21906829/1587329
serv-inc

18

นี่คือรหัสที่คุณต้องตั้งค่าสรุปให้เป็นค่าที่เลือก นอกจากนี้ยังตั้งค่าเมื่อเริ่มต้นและเคารพค่าเริ่มต้นไม่เพียง แต่ในการเปลี่ยนแปลง เพียงแค่เปลี่ยน "R.layout.prefs" เป็นไฟล์ xml ของคุณและขยาย setSummary- วิธีการตามความต้องการของคุณ อันที่จริงมันเป็นเพียงการจัดการ 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";
}

koem


ขอบคุณมาก! ฉันสร้างคลาสจากสิ่งนี้โดยให้รหัสทรัพยากรเป็นอาร์กิวเมนต์ของ onCreate () - วิธีนี้เป็นการเปลี่ยนบรรทัดหนึ่งไปยังหน้าจอการตั้งค่าของฉันเพื่อให้พวกเขาแสดงค่าโดยสรุป
Asmo Soinio

2
BTW: โปรดทราบว่าการตั้งค่าแบบไม่ถาวรจะไม่ได้รับการอัพเดตโดยใช้ระบบนี้ การเปลี่ยนแปลงเหล่านั้นจะต้องฟังโดยใช้วิธีการsetOnPreferenceChangeListener(Preference.OnPreferenceChangeListener onPreferenceChangeListener)ของการตั้งค่าของแต่ละบุคคล
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

หากใครบางคนยังคงมองหาคำตอบนี้คุณควรตรวจสอบคำตอบที่สามสิบ

<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


โรงงาน นี่เป็นทางออกที่ง่ายที่สุดและดีที่สุดในวันนี้
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 เพื่อให้ทำงานกับ SDK สำหรับ Android 1.5

@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") ค่ารายการปัจจุบันจะถูกแทนที่ในตำแหน่งนั้น

อย่างไรก็ตามฉันลองกับอุปกรณ์หลายเครื่องแล้วดูเหมือนจะไม่ทำงาน ด้วยการวิจัยบางอย่างฉันพบวิธีแก้ปัญหาที่ดีในคำตอบนี้ มันประกอบด้วยการขยายทุกอย่างที่Preferenceคุณใช้และแทนที่getSummary()เพื่อทำงานตามที่ระบุไว้ในเอกสาร Android


1
ดูเหมือนจะใช้งานได้ในตอนแรก แต่เมื่อคุณเลือกค่าใหม่มันจะไม่อัปเดตโดยอัตโนมัติจนกว่าคุณจะทำอะไรบางอย่างเพื่อทำให้กิจกรรมทั้งหมดไม่ถูกต้องและทำให้เกิดการวาดใหม่ ฉันใช้ Android 4.0.4
eidylon

จะดีถ้า Google สามารถเพิ่มสตริงการจัดรูปแบบวัตถุการตั้งค่า
Justin Smith

3

หากคุณต้องการแสดงค่าข้อความล้วนของแต่ละฟิลด์เป็นข้อมูลสรุปรหัสต่อไปนี้ควรเป็นวิธีที่ง่ายที่สุดในการรักษา ต้องการการเปลี่ยนแปลงเพียงสองรายการ (บรรทัดที่ 13 และ 21 ที่มีเครื่องหมายว่า "change here"):

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

FYI:

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


2

นี่คือทั้งหมดที่ถูกตัดจากตัวอย่าง Eclipse SettingsActivityที่นี่ทั้งหมดเหล่านี้จะถูกตัดออกจากกลุ่มตัวอย่างคราสฉันต้องคัดลอกรหัสที่มากเกินไปเหล่านี้เพื่อแสดงให้เห็นว่านักพัฒนา Android เหล่านี้เลือกวิธีการเข้ารหัสแบบทั่วไปและมีเสถียรภาพมากขึ้นได้อย่างไร

ฉันออกจากรหัสเพื่อปรับ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>

หมายเหตุ:จริงๆแล้วฉันแค่ต้องการแสดงความคิดเห็นเช่น "ตัวอย่างของ Google สำหรับ PreferenceActivity ก็น่าสนใจเช่นกัน" แต่ฉันมีคะแนนชื่อเสียงไม่เพียงพอดังนั้นโปรดอย่าตำหนิฉัน

(ขออภัยภาษาอังกฤษที่ไม่ดี)


2

คุณต้องใช้ฟังก์ชัน bindPreferenceSummaryToValue บนวิธีการ onCreate

ตัวอย่าง:

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

ดูบทที่ 3 เกี่ยวกับหลักสูตร Udacity Android: https://www.udacity.com/course/viewer#!/c-ud853/l-1474559101/e-1643578599/m-1643578601


2

สำหรับ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.ListPreferenceวัตถุของคุณในpreferences.xmlความทรงจำเพื่อระบุมีของคุณเป็นทริกเกอร์นี้เรียกร้องให้android:defaultValueonSetInitialValue()

หากคุณต้องการคุณสามารถแก้ไขข้อความก่อนโทรsetSummary()ไปยังแอปพลิเคชันของคุณ


1

เนื่องจากฉันใช้แบบกำหนดเอง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 คุณสามารถใช้กำหนดเองSummaryProviderได้ Preferenceวิธีการนี้สามารถนำมาใช้สำหรับการใด ๆ

ตัวอย่างจากเอกสาร (Java):

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.