Kotlin:如何在PreferenceFragment中自定义视图

2023-05-16

前几天项目开发中需要用kotlin做一个类似Android原生settings的页面,只不过ui相较preference自带的控件有些变化,特别是ListPreference的数据更新问题,困扰了好久,网上也只有只言片语聊到这个,所以记录下心得。

使用PreferenceFragment最主要的好处有两点:

  • 实现了Material Design,页面设计更简洁操作方便。
  • 能够自动将用户设置的状态或值存入SharedPreference中。

1. 如何在代码中使用preferenceFragment

首先,需要在values目录下创建一个xml目录用来保存prefernce的ui资源:pref_test.xml

 具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen android:title="Settings"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <PreferenceCategory
        android:layout="@layout/layout_settings"
        android:key="pre_back_key">
    </PreferenceCategory>
    
    <PreferenceCategory android:title="Function1"
        android:layout="@layout/layout_pre_title"
        app:allowDividerAbove="true"
        app:allowDividerBelow="true"
        app:iconSpaceReserved="false">

        <SwitchPreference
            android:key="switch_key"
            android:defaultValue="true"
            app:iconSpaceReserved="false"
            app:allowDividerAbove="true"
            app:allowDividerBelow="true"
            android:title="switch"/>

        <ListPreference
            android:key="pre_led_key"
            android:entries="@array/display_led"
            android:dialogTitle="led"
            android:entryValues="@array/display_led_value"
            app:iconSpaceReserved="false"
            app:allowDividerAbove="true"
            app:allowDividerBelow="true"
            android:title="Led"
            android:widgetLayout="@layout/layout_pre_led"
            android:summary="blue, red, off"
            app:defaultValue="0"/>

    </PreferenceCategory>
    
</androidx.preference.PreferenceScreen>

key: 当前控件在SharedPreference存储中的key

title: 当前preference的标题

summary: 子标题

entries: 用户在列表中可以选择的值,可以在string.xml中设置string-array

entryValues: entries在SharedPreference中对应key的values

iconSpaceReserved: 默认是true,代表此preference一栏的最前面留有一个放置图片的空间,如果不需要的话可以设置成false

allowDividerAbove/allowDividerBelow: 指在此行上下是否显示分割线

dialogTitle: 弹出的选择框的标题

widgetLayout: 右侧独立的小块布局,可以自定义layout

<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/widget_frame"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:src="@drawable/go"/>

一个简单的preference布局就完成了


然后新建一个TestPreferenceFragment继承PreferenceFragmentCompat

class TestPreferenceFragment(private var spName : String) : PreferenceFragmentCompat(),
    Preference.OnPreferenceChangeListener{

    private var testTag = "TestPreferenceFragment"
    private lateinit var mLuminosityListPre: ListPreference


    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        Log.d(testTag, "onCreatePreferences")
        preferenceManager.sharedPreferencesName = spName
        setPreferencesFromResource(R.xml.pref_test, rootKey)
        initAllPre()
    }

    /*override fun onPreferenceTreeClick(preference: Preference?): Boolean {
        Log.d(testTag, "onPreferenceTreeClick: ${preference!!.key}")
        return super.onPreferenceTreeClick(preference)
    }*/

    override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
        if (preference != null) {
            Log.d(testTag, "onPreferenceChange -> preference.key: ${preference.key}" + ", preference.value: $newValue")
        }
        return true
    }



    private fun initAllPre() {
        mLuminosityListPre = findPreference(Constant.PRE_LUMINOSITY_KEY)!!
        mLuminosityListPre.onPreferenceChangeListener = this

    }

在onCreatePreferences方法中调用setPreferencesFromResource将之前创建的pref_test.xml传入也可以通过preferenceManager.sharedPreferencesName设置SharedPreference的文件名方便查找。

onPreferenceChange: 可以监听用户对所有preference的值的更改

onPreferenceTreeClick: 监听点击事件

2.自定义preference控件原生UI

需要添加: android:layout="@layout/layout_pre_luminosity" 来填充自定义的视图

        <ListPreference
            android:key="pre_Luminosity_key"
            android:entries="@array/luminosity"
            android:dialogTitle="Luminosity"
            android:entryValues="@array/luminosity_value"
            app:allowDividerAbove="true"
            app:defaultValue="0"
            app:allowDividerBelow="true"
            android:icon="@drawable/go"
            android:title="Luminosity"
            android:summary="@string/luminosity_auto"
            android:layout="@layout/layout_pre_luminosity"
            android:widgetLayout="@layout/layout_widget"
            app:iconSpaceReserved="false"/>

 重点来了,当你传入了自定义的layout之后,所有的控件id得根据preference_material.xml中原生定义的控件id设置你自己的控件id,不然会出现无法更新数据的问题!!!

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:paddingBottom="7dp"
    android:paddingTop="7dp"
    android:layout_height="wrap_content">

    <TextView
        android:id="@android:id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginStart="15dp"
        android:textColor="#000000"
        android:textSize="16sp" />

    <ImageView
        android:id="@android:id/icon"
        android:layout_width="30dp"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:layout_height="30dp"
        android:src="@drawable/go"/>

    <TextView
        android:id="@android:id/summary"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="30dp"
        android:text="Auto"
        android:textSize="18sp" />

    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_alignParentEnd="true"
        android:layout_below="@android:id/summary"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginEnd="30dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="10sp"
            android:text="(Auto, High, Mid, Low)"/>
    </LinearLayout>

</RelativeLayout>

 

3.数据更新

 当我们控制添加完的控件进行开关或者选项切换时将会触发onPreferenceChange()方法,根据传入的value进行对应的数据更新即可。

    override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
        if (preference != null) {
            Log.d(testTag, "onPreferenceChange -> preference.key: ${preference.key}" + ", preference.value: $newValue")
            setListPreData(preference.key, newValue)
        }
        return true
    }

    private fun setListPreData(preKey: String, newValue : Any?) {
        Log.d(testTag, "preKey: $preKey + ------ value: $newValue")
        when (preKey) {

            Constant.PRE_LUMINOSITY_KEY -> {
                when (newValue) {
                    "0" -> mLuminosityListPre.summary = getString(R.string.luminosity_auto)
                    "1" -> mLuminosityListPre.summary = getString(R.string.luminosity_high)
                    "2" -> mLuminosityListPre.summary = getString(R.string.luminosity_mid)
                    "3" -> mLuminosityListPre.summary = getString(R.string.luminosity_low)
                }

            }
        }
    }

由于笔者时间紧张,所以没有进一步研究是否可以对layout中的id属性进行扩展,各位可以自行研究。 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kotlin:如何在PreferenceFragment中自定义视图 的相关文章

  • Android WebView https白屏、Http和Https混合问题、证书配置和使用

    目录 前言启用https后白屏 xff08 证书错误 xff09 修改处理WebView中Http和Https混合问题处理办法Webview的几种内容加载模式 证书配置或处理https请求的证书okhttp进行请求 xff1a HttpsU
  • Java错误:找不到或无法加载主类

    目录 前言javac xxx java 编译需要相对物理路径java xxx 执行需要虚拟路径总结 前言 一般情况下 xff0c 我们都使用工具进行代码的编辑和调试 xff0c 例如eclipse Manven Android Studio
  • Edge 修改字符编码(详细图文)

    Microsoft Edge 版本 97 0 1072 62 官方内部版本 64 位 前言 如下图 xff0c 在访问页面时出现乱码 xff0c 而且一直返回的内容编码是UTF 8 xff0c 但Edge没找快捷的编码方式选择 方法一 In
  • Charles抓取HTTPS Windows Android iOS 图文详细

    文章目录 背景操作原理windows 安装CharlesCharles配置第一步 xff1a 配置HTTP代理 xff0c 这步与抓取HTTP请求是一样第二步 xff1a 配置SSL代理第三步 xff1a 为手机配置代理iPhone 代理配
  • Linux less 命令使用介绍

    文章目录 1 xff0e 命令格式2 xff0e 命令功能3 xff0e 命令参数4 xff0e 按键操作5 xff0e 示例1 查看文件内容2 ps查看进程信息并通过less分页显示3 查看命令历史使用记录并通过less分页显示5 浏览多
  • macOS/iOS WKWebview 下载文件

    WKWebview 下载文件需要通过JS注入的方式来下载 js下载的数据是base64编码的 xff0c 回到给原生后 xff0c 原生需要反编码后才是原始文件的数据 具体步骤 xff1a 配置WKWebview的js回调句柄 xff08
  • 【uniapp原生插件】招商银行一网通支付android&iOS

    招行支付插件说明 参考uni插件市场 wx gaogaoEagle 插件集成准备 从招行获得appid和appSchememanifest json中App原生插件配置 xff0c 云端插件选择试用或购买的插件 xff0c 并配置Andro
  • mongodb命令使用

    设置慢查询 db setProfilingLevel 1 200 查询副本集当前状况 需要将命令行切换到需要查询的副本集中 rs status 查询数据库当前情况 sh status 查询数据分片情况 db 集合名称 getShardDis
  • Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.5.0-runtime

    冲突问题 androidx和support类冲突 xff0c 具体如下 xff1a Duplicate class android support v4 app INotificationSideChannel found span cla
  • 关于I帧/IDR、B帧、P帧、SPS、PPS

    在h264编解码中 xff0c 常常有I帧 IDR B帧 P帧 IDR NALU GOP xff0c 但往往没有关注细节 或者我们本身在实际应用中已使用过很多次 xff0c 但对相关的技术名词不清楚 在H264协议里定义了三种帧 xff0c
  • 如何保证数据库与缓存的数据一致性

    一 先删缓存 xff0c 再修改数据库 数据不一致的情况 一 线程A修改数据时 xff0c 需先执行删除缓存操作 二 其他线程只要在线程A删除缓存和执行update期间 xff0c 查询数据库得到了旧的数据 xff0c 此时就有极大的概率会
  • spring-jms/DefaultMessageListenerContainer配置

    一个DefaultMessageListenerContainer可以开启多个 concurrent AsyncMessageListenerInvoker并发 收消息 两种模式 模式一 xff1a 递增监听线程并调度 xff0c 监听线程
  • IDEA的Git操作——拉取、对比开发代码

    一 git原理 git是一个分布式的版本管理工具 xff0c 主要分为2个部分 xff1a 本地 xff1a 分为3个区 xff1a working space xff08 工作区 xff09 staging area xff08 暂存区
  • .sh文件无法执行

    sh文件无法执行 解决方法 xff1a chmod x xxx sh
  • html页面中查找元素 css

    1 根据某标签获取上层父标签 lt div id 61 34 div1 34 class 61 34 div1 34 gt lt a gt lt input type 61 34 text 34 gt lt img id 61 34 img
  • maven配置详解

    下载地址 xff1a Maven Download Apache Maven xff0c 添加环境变量 xff1a MAVEN HOME 一 配置文件 maven的配置文件主要有 settings xml 和pom xml 两个文件 1 其
  • 我的2014碎碎念—学习篇、实习篇、工作篇、生活篇

    继去年作了一次年度总结过后 xff0c 我就发誓说以后每年年末都要做一次总结 xff0c 这对自己是非常有帮助的 xff0c 无奈由于天性懒散 xff0c 2015年都过去好几天了 xff0c 才花了点心思整理下自己在过去一年里的所得所失
  • 百度2014研发类校园招聘笔试题解答

    先总体说下题型 xff0c 共有3道简答题 xff0c 3道算法编程题和1道系统设计题 xff0c 题目有难有易 xff0c 限时两小时完成 一 简答题 动态链接库和静态链接库的优缺点轮询任务调度和可抢占式调度有什么区别 xff1f 列出数
  • Rt-thread encoder 编码器不会溢出中断问题

    参考文章https blog csdn net qq 41285788 article details 102729020 并参考按照官方文档指导 xff0c 编译成功后下载运行测试发现 xff0c 虽然编码能计数 xff0c 但不能产生溢
  • 一个比较不错的CMD样式

    64 echo off reg add 34 HKEY CURRENT USER Console SystemRoot system32 cmd exe 34 ve f 1 gt nul reg add 34 HKEY CURRENT US

随机推荐