【问题标题】:Display the value of the EditTextPreference in summary [duplicate]在摘要中显示 EditTextPreference 的值 [重复]
【发布时间】:2016-03-21 05:25:25
【问题描述】:

我是一个学习如何在Android中开发并想做一个设置活动,

我的设置活动

public class Main extends Activity  {


    protected SettingsFragment settingsFragment;


    @SuppressLint("NewApi")
    @TargetApi(11)
    public class SettingsFragment extends PreferenceFragment implements
            SharedPreferences.OnSharedPreferenceChangeListener {


        @Override
        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
            setSummaries();


        }


        @Override
        public void onResume() {
            final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
            super.onResume();
            sh.registerOnSharedPreferenceChangeListener(this);

        }

        @Override
        public void onPause() {
            final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
            super.onPause();
            sh.unregisterOnSharedPreferenceChangeListener(this);
        }

        @SuppressLint("NewApi")
        public void setSummaries(){

           final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;


            //Pref1
            Preference stylePref = findPreference("editTextPref");
            stylePref.setSummary(sh.getString("editTextPref", ""));

            //here the other preferences..
        }


        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            if (key.equals("editTextPref")) {
                Preference pref = settingsFragment.findPreference(key);
                // Set summary to be the user-description for the selected value
                pref.setSummary(sharedPreferences.getString(key, ""));

            }
            //here the others preferences
        }
    }//End fragment

    @SuppressLint("NewApi")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        settingsFragment = new SettingsFragment();
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, settingsFragment)
                .commit();


    }


}

还有我的res/preferences.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="BTA"
        xmlns:android="http://schemas.android.com/apk/res/android">


        <EditTextPreference
            android:key="editTextPref"
            android:title="Numero de telephone"
            android:summary="This allows you to enter a string"
            android:defaultValue="*"/>

    </PreferenceCategory>

</PreferenceScreen>

所以现在我有了设置活动的活动。但我想在android:summary 中显示 EditTextPref 的值。 我发现了很多主题,但所有功能都已弃用。

编辑:感谢@Ace_McIntosh,我为需要它的人编辑了我的代码,它现在可以工作了。

【问题讨论】:

    标签: android


    【解决方案1】:

    如果您使用AndroidX Preference library,您可以使用属性app:useSimpleSummaryProvider。例如:

    <EditTextPreference
            app:key="edittext"
            app:title="@string/title_edittext_preference"
            app:useSimpleSummaryProvider="true"
            app:dialogTitle="@string/dialog_title_edittext_preference"/>
    

    您可以阅读完整的工作示例here

    【讨论】:

    • 这也应该被接受为答案。同样在运行时:preference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance() //kotlin
    【解决方案2】:

    只需覆盖EditTextPreference 中的getSummary,然后您将获得一个EditTextPreference,其值显示为摘要。

    public class EditSummaryPreference extends EditTextPreference {
        ...// omit constructor
    
        @Override
        public CharSequence getSummary() {
            return getText();
        }
    }
    

    【讨论】:

    • 这实际上是最简单的答案,因为它不需要更改片段或活动中的任何代码或与如何处理或创建设置相关的任何代码。
    • 但是如果用户更改了值,摘要不会更新,是吗?
    【解决方案3】:

    只需在所需的 Preference 对象上使用 setSummary method。在恢复您希望更新的每个条目的设置片段时调用它(即,您的案例中的所有EditTextPreference 条目)并在具体的SharedPreferences 对象上注册一个OnSharedPreferenceChangeListener(以便您可以更新摘要如果它被改变了)——并传递给它所需的 EditTextPreference 的值(你可以通过它的getText() 方法获得)。

    像这样在你的MyPreferenceFragment 中实现它(我不保证它会正确地工作,它的目的只是给你一个想法):

    public class MyPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
        SharedPreferences sharedPreferences;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // load the preferences from your XML resource (which I assume you already do anyway)
            addPreferencesFromResource(R.xml.preferences);
        }
    
        @Override
        public void onResume() {
            super.onResume();
    
            sharedPreferences = getPreferenceManager().getSharedPreferences();
    
            // we want to watch the preference values' changes
            sharedPreferences.registerOnSharedPreferenceChangeListener(this);
    
            Map<String, ?> preferencesMap = sharedPreferences.getAll();
            // iterate through the preference entries and update their summary if they are an instance of EditTextPreference
            for (Map.Entry<String, ?> preferenceEntry : preferencesMap.entrySet()) {
                if (preferenceEntry instanceof EditTextPreference) {
                    updateSummary((EditTextPreference) preferenceEntry);
                }
            }
        }
    
        @Override
        public void onPause() {
            sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
            super.onPause();
        }
    
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
                                              String key) {
            Map<String, ?> preferencesMap = sharedPreferences.getAll();
    
            // get the preference that has been changed
            Object changedPreference = preferencesMap.get(key);
            // and if it's an instance of EditTextPreference class, update its summary
            if (preferencesMap.get(key) instanceof EditTextPreference) {
                updateSummary((EditTextPreference) changedPreference);
            }
        }
    
        private void updateSummary(EditTextPreference preference) {
            // set the EditTextPreference's summary value to its current text
            preference.setSummary(preference.getText());
        }
    }
    

    【讨论】:

    • 问题是 addPreferencesFromResource 已被弃用。
    • 它仅在 PreferenceActivity 类中被弃用,你必须在 PreferenceFragment 类中调用它(它未被弃用,如你所见 in the documentation)。请务必使用该片段(您尚未发布它的代码,我只看到您在活动类中创建了MyPreferenceFragment 的新实例)。另请注意,PreferenceFragment 的父活动不必扩展PreferenceActivity,它可以只是一个普通活动。
    • 您需要通过SharedPreferences 对象的registerOnSharedPreferenceChangeListener 方法为偏好更改注册一个侦听器,并在侦听器中处理更新。在我发布给您的代码中有一个如何执行此操作的示例,所说的侦听器是类 MyPreferenceFragment 本身(它必须实现适当的接口),并且您可以看到它包含您应该更新的 onSharedPreferenceChanged 回调正在更改的首选项的摘要。如果您这样做,则每次偏好值更改时都会更新摘要。
    • 您应该将该代码放在onResume() 生命周期方法中,因为每次片段进入前台时都需要调用它。我建议您将 sh 变量作为类字段引入,并在您的 onResume() 中调用:sh.registerOnSharedPreferenceChangeListener(Main.this)。并且不要忘记在onPause()方法中取消注册回调,使用sh.unregisterOnSharedPreferenceChangeListener(Main.this)(如果你不这样做,你可能会在放弃并返回设置片段并调用监听器时得到一个空指针异常) .
    • 是的,并使您的SettingsFragment 类可实例化,而不是静态的,否则您将无法访问父对象。为了使事情更方便,我建议您保持父活动类干净并让片段实现 SharedPreferences.OnSharedPreferenceChangeListener 代替 - 这样,您将能够重用您的 SharedPreferences 类字段(在引入它之后,前提是你愿意)。
    【解决方案4】:

    (在 Kotlin 中)我更愿意做一些更简单的事情,只创建一个扩展 EditTextPreference 的类:

    import android.content.Context
    import android.support.v7.preference.EditTextPreference
    import android.util.AttributeSet
    
    /**
     * This class was created by Anthony M Cannon on 17/04/2018.
     */
    class SummarisedEditTextPreference @JvmOverloads constructor(context: Context,
        attrs: AttributeSet? = null) : EditTextPreference(context, attrs) {
    
        private var mOnChangeListener: OnPreferenceChangeListener? = null
    
        init {
            super.setOnPreferenceChangeListener { preference, newValue ->
                summary = newValue as String
                mOnChangeListener?.onPreferenceChange(preference, newValue) ?: true
            }
        }
    
        /**
        * Called when this Preference has been attached to a Preference hierarchy.
        * Make sure to call the super implementation.
        *
        * @param preferenceManager The PreferenceManager of the hierarchy.
        */
        override fun onAttachedToHierarchy(preferenceManager: PreferenceManager) {
            super.onAttachedToHierarchy(preferenceManager)
            summary = sharedPreferences.getString(key, null)
        }
    
    
        /**
         * Sets the callback to be invoked when this Preference is changed by the
         * user (but before the internal state has been updated).
         *
         * @param onPreferenceChangeListener The callback to be invoked.
         */
        override fun setOnPreferenceChangeListener(
            onPreferenceChangeListener: OnPreferenceChangeListener) {
            mOnChangeListener = onPreferenceChangeListener
        }
    }
    

    然后你可以像这样使用它:

    &lt;.SummarisedEditTextPreference/&gt;

    【讨论】:

    • '@JvmOverloads' 的构造函数在这种情况下不起作用,'EditTextPreferences' 的样式将不会应用,因为你没有以这种方式调用'super' 构造函数。尝试'构造函数(上下文:上下文):超级(上下文)构造函数(上下文:上下文,attrs:AttributeSet?):超级(上下文,attrs)构造函数(上下文:上下文,attrs:AttributeSet?,defStyleAttr:Int):超级(上下文, attrs, defStyleAttr)' 代替。
    【解决方案5】:

    androidx 库 中,EditTextPreference 具有app:useSimpleSummaryProvider 属性。使用该属性,您无需扩展任何类或监听 SharedPreferences 上的任何更改。您可以在https://github.com/googlesamples/android-preferences/blob/master/app/src/main/res/xml/dialogs.xml查看示例代码

    【讨论】:

    • 请不要发布解决方案的链接。仅使用它们来备份您的解决方案
    • 太棒了!无需对代码进行任何更改。实际的 xml 是 app:useSimpleSummaryProvider="true",它是在 preference:1.1.0-alpha01 中添加的
    【解决方案6】:

    上面发布的示例中有一些错误,所以我认为我发布了一个可行的解决方案(也支持 ListPreference 和 MultiSelectListPreference)

    public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
    
    private SharedPreferences sharedPreferences;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
    }
    
    @Override
    public void onResume() {
        super.onResume();
    
        sharedPreferences = getPreferenceManager().getSharedPreferences();
        sharedPreferences.registerOnSharedPreferenceChangeListener(this);
    
        PreferenceScreen preferenceScreen = getPreferenceScreen();
        for(int i = 0; i < preferenceScreen.getPreferenceCount(); i++) {
            setSummary(getPreferenceScreen().getPreference(i));
        }
    }
    
    @Override
    public void onPause() {
        sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
        super.onPause();
    }
    
    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        Preference pref = getPreferenceScreen().findPreference(key);
        setSummary(pref);
    }
    
    private void setSummary(Preference pref) {
        if (pref instanceof EditTextPreference) {
            updateSummary((EditTextPreference) pref);
        } else if (pref instanceof ListPreference) {
            updateSummary((ListPreference) pref);
        } else if (pref instanceof MultiSelectListPreference) {
            updateSummary((MultiSelectListPreference) pref);
        }
    }
    
    private void updateSummary(MultiSelectListPreference pref) {
        pref.setSummary(Arrays.toString(pref.getValues().toArray()));
    }
    
    private void updateSummary(ListPreference pref) {
        pref.setSummary(pref.getValue());
    }
    
    private void updateSummary(EditTextPreference preference) {
        preference.setSummary(preference.getText());
    }
    }
    

    【讨论】:

    • 对于 ListPreferences,您可以使用 'android:summary="%s"' 将值显示为摘要。
    【解决方案7】:

    @serv-inc 的答案对我有用。不知何故,其他答案仅在值更改时才有效。

    但在它起作用之前,我必须进行如下更改:

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

    它在初始显示时、值更改时以及恢复后显示值。

    【讨论】:

    • 您必须更改 getSummary() 因为@serv-inc 答案将 android:summary="Actual value: %s" 字段设置为用于字符串格式。
    【解决方案8】:

    以 Brett Cherringtons 的回答为基础,在 Kotlin 中实现。有一个错误,即不支持 PreferenceCategories,通过 setSummary 中的附加递归循环修复了该错误

    class SettingsFragment : PreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
    
        private lateinit var sharedPreferences: SharedPreferences
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            addPreferencesFromResource(R.xml.preferences)
        }
    
        override fun onResume() {
            super.onResume()
    
            sharedPreferences = preferenceManager.sharedPreferences
            sharedPreferences.registerOnSharedPreferenceChangeListener(this)
    
            val preferenceScreen = preferenceScreen
            for (i in 0 until preferenceScreen.preferenceCount) {
                setSummary(getPreferenceScreen().getPreference(i))
            }
        }
    
        override fun onPause() {
            sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
            super.onPause()
        }
    
        override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
            val pref = preferenceScreen.findPreference(key)
            pref?.let { setSummary(it) }
        }
    
        private fun setSummary(pref: Preference) {
            if (pref is EditTextPreference) {
                updateSummary(pref)
            } else if (pref is ListPreference) {
                updateSummary(pref)
            } else if (pref is MultiSelectListPreference) {
                updateSummary(pref)
            } else if (pref is PreferenceCategory){
                // needs to loop through child preferences
                for (i in 0 until pref.preferenceCount) {
                    setSummary(pref.getPreference(i))
                }
            }
        }
    
        private fun updateSummary(pref: MultiSelectListPreference) {
            pref.setSummary(Arrays.toString(pref.values.toTypedArray()))
        }
    
        private fun updateSummary(pref: ListPreference) {
            pref.summary = pref.value
        }
    
        private fun updateSummary(preference: EditTextPreference) {
            preference.summary = preference.text
        }
    }
    

    【讨论】:

      【解决方案9】:

      除了@Eke Koseoglu 的回答。

      如果您使用 AndroidX 偏好库​​strong>,您可以从下面的 Kotlin 代码中设置 summaryProvider

      val editTextPreference = EditTextPreference(context)
      editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()
      

      根据EditTextPreference.SimpleSummaryProvider的文档;

      如果未设置任何值,则显示的摘要将为“未设置”, 否则显示的摘要将是为此设置的值 偏好。

      【讨论】:

      • 如何从键中获取值,例如app:key="city"?
      猜你喜欢
      • 1970-01-01
      • 2012-10-05
      • 1970-01-01
      • 2019-10-08
      • 2011-12-10
      • 1970-01-01
      • 2018-09-03
      • 2018-03-24
      • 1970-01-01
      相关资源
      最近更新 更多