Kotlin中替代已弃用PreferenceFragment实现字体设置方案咨询
问题描述
旧Java应用使用已弃用的PreferenceFragment,通过ActionBar下拉菜单实现字体大小和类型调整,现在需要迁移到Kotlin,要求:
- 沿用原有XML配置和资源文件,不使用基于Room的Preferences
- 用
PreferenceManager保存用户选择 - 保持「点击ActionBar下拉菜单→进入设置页→选择字体参数」的交互流程
- 仅允许选择预设的字体大小和类型,不接受自定义输入
原有配置文件和Java代码如下:
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <ListPreference android:entries="@array/font_size" android:entryValues="@array/fvalues" android:key="fong" android:summary="Click here to choose a font size" android:title="Select Font Size" /> <ListPreference android:entries="@array/font_name" android:entryValues="@array/font_ttf" android:key="fonz" android:summary="Click here to change font" android:title="Select Font" /> </PreferenceScreen>
资源文件:
<resources> <string-array name="font_size"> <item>Huge</item> <item>Large</item> <item>Normal</item> <item>Small</item> <item>Tiny</item> </string-array> <string-array name="fvalues"> <item>28</item> <item>24</item> <item>20</item> <item>16</item> <item>12</item> </string-array> <string-array name="font_name"> <item>Note</item> <item>Flower</item> </string-array> <string-array name="font_ttf"> <item>Note_this.ttf</item> <item>IndieFlower.ttf</item> </string-array> </resources>
原Java ActionBar代码:
public boolean onOptionsItemSelected(MenuItem item) { int itemId = item.getItemId(); if (itemId == R.id.action_settings) { Intent p = new Intent("app.sticky_notes.PREFS"); startActivity(p); } return false; }
原Java PreferenceActivity代码:
public class Prefs extends PreferenceActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new Pref_frag()).commit(); } public static class Pref_frag extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.prefs); } } }
原Java获取偏好设置代码:
public int get_font_size() { SharedPreferences get_prefs = PreferenceManager.getDefaultSharedPreferences(this); String font_string = get_prefs.getString("fong", "24"); font_size = Integer.parseInt(font_string); return font_size; } public String get_font_name() { SharedPreferences get_prefs = PreferenceManager.getDefaultSharedPreferences(this); font_name = get_prefs.getString("fonz", "Note_this.ttf"); return font_name; }
Kotlin替代实现方案
1. 复用原有配置文件
你提供的res/xml/prefs.xml和资源数组文件可以直接复用,无需修改。
2. 实现设置页面(替代弃用的PreferenceFragment)
使用AndroidX的PreferenceFragmentCompat替代旧的PreferenceFragment,它是官方推荐的兼容方案,且依然支持PreferenceManager的默认SharedPreferences存储。
首先确保项目依赖AndroidX Preference库(未添加则在build.gradle(Module level)中加入):
dependencies { implementation "androidx.preference:preference-ktx:1.2.1" }
编写Kotlin版设置Activity和Fragment:
设置Activity (PrefsActivity.kt)
import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.preference.PreferenceFragmentCompat class PrefsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportFragmentManager.beginTransaction() .replace(android.R.id.content, SettingsFragment()) .commit() } class SettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.prefs) } } }
在AndroidManifest.xml中注册该Activity:
<activity android:name=".PrefsActivity" android:label="Settings"> <intent-filter> <action android:name="app.sticky_notes.PREFS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
3. ActionBar菜单点击处理(Kotlin版)
在主Activity中重写菜单点击方法,跳转至设置页:
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_settings -> { startActivity(Intent("app.sticky_notes.PREFS")) true } else -> super.onOptionsItemSelected(item) } }
4. 获取用户偏好设置(Kotlin版)
通过PreferenceManager读取保存的配置,逻辑与原Java版本一致:
fun getFontSize(): Int { val prefs = PreferenceManager.getDefaultSharedPreferences(this) val fontSizeString = prefs.getString("fong", "24") ?: "24" return fontSizeString.toInt() } fun getFontName(): String { val prefs = PreferenceManager.getDefaultSharedPreferences(this) return prefs.getString("fonz", "Note_this.ttf") ?: "Note_this.ttf" }
关键说明
PreferenceFragmentCompat完全兼容原有ListPreference配置,用户只能选择预设选项,无法输入自定义内容- 用户选择仍存储在默认SharedPreferences中,与旧Java版本存储位置一致,无需迁移数据
- 完全保留原有交互流程,用户体验无变化
内容的提问来源于stack exchange,提问作者MunterMan
相关产品推荐
相关产品推荐

