总结安卓Preference使用过程中注意的问题

近期在做新项目中接触到了Preference,这是一种用户界面元素,用于存储和展示应用程序的各种设置和用户偏好。该控件几年前google就已经发布了只是一直没机会应用,其实用起来还是挺方便的,使用过程中遇到了几个问题在此记录下。

1、自定义Preference在屏幕显示时宽度没有充满屏幕

java 复制代码
constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr) {
        //主要是这个点需要调用setLayoutResource而不是setWidgetLayoutResource
        layoutResource = R.layout.preference_icon_title_layout
        val config = context.obtainStyledAttributes(
            attrs,
            R.styleable.IconTitlePreference,
            defStyleAttr,
            defStyleRes
        )
        //获取属性
        mTitle = config.getString(R.styleable.IconTitlePreference_settingTitle)
        config.recycle()
    }

2、release包打开Preference相关页面出现闪退

java 复制代码
<Preference
        app:fragment="aaa.bbb.ccc.fragment.DemoFragment"
        app:title="@string/settings_adblock" />

如果在xml你通过fragment属性配置了跳转页面的话,闪退问题是混淆导致的,最好是将fragment属性指定的fragment放到同一个文件夹下,然后配置整个目录不被混淆

java 复制代码
-keep class aaa.bbb.ccc.fragment.**{*;}

3、顶部返回按钮回退处理

通常我们在父Activity里实现PreferenceFragmentCompat.OnPreferenceStartFragmentCallback来监听onPreferenceStartFragment回调,然后获取要打开的fragment添加到布局中

java 复制代码
    override fun onPreferenceStartFragment(
        caller: PreferenceFragmentCompat,
        pref: Preference
    ): Boolean {
        val args = pref.extras
        val fragment = supportFragmentManager.fragmentFactory.instantiate(
            classLoader,
            pref.fragment!!
        )
        fragment.arguments = args
        fragment.setTargetFragment(caller, 0)
        supportFragmentManager.beginTransaction()
        	//可以在这里设置fragment启动动画
            .setCustomAnimations(
                R.anim.slide_in_from_right,
                R.anim.fade_out_scale,
                R.anim.fade_in_scale,
                R.anim.slide_out_to_right
            )
            .replace(R.id.root, fragment)
            //这个方法一定要调用,为了将当前fragment添加到回退栈中,用于下面的popBackStackImmediate调用
            .addToBackStack(null)
            .commit()
        return true
    }

顶部title的返回键处理

java 复制代码
findViewById<ImageView>(R.id.setting_page_title).setOnClickListener {
			//如果直接finish的话,无论你fragment层级有多深都会全部关闭
			//popBackStackImmediate从回退栈中弹出当前fragment,弹出成功会返回true
			//如果是到达了父容器层级时会返回false,这时候直接finish即可
            if (!supportFragmentManager.popBackStackImmediate()) {
                finish()
            }
        }

最后总结下自定义Preference的使用

java 复制代码
class SuperPreference : Preference {

    private var mTitle : String?
    private lateinit var mIconIv : ImageView

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attrs: AttributeSet?) : this(
        context,
        attrs,
        R.attr.preferenceStyle
    )

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(
        context,
        attrs,
        defStyleAttr,
        0
    )

    constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr) {
        //替换布局
        layoutResource = R.layout.preference_icon_title_layout
        val config = context.obtainStyledAttributes(
            attrs,
            //自定义的属性
            R.styleable.IconTitlePreference,
            defStyleAttr,
            defStyleRes
        )
        //获取属性
        mTitle = config.getString(R.styleable.IconTitlePreference_settingTitle)
        config.recycle()
    }

    override fun onBindViewHolder(holder: PreferenceViewHolder) {
        super.onBindViewHolder(holder)
        //在这里对控件的findViewById初始化操作
        mIconIv = holder.findViewById(R.id.setting_icon) as ImageView
       //对控件进行赋值等操作
    }
}
相关推荐
alexhilton13 小时前
深入浅出着色器:极坐标系与炫酷环形进度条
android·kotlin·android jetpack
bytebeats2 天前
Jetpack Compose 1.8 新增了 12 个新特性
android·android jetpack
MettBarr4 天前
Jetpack Lifecycle 的本质
android jetpack
刘龙超4 天前
如何应对 Android 面试官 -> 运用 Jetpack 写一个音乐播放器(五)完结
android jetpack
alexhilton4 天前
用Compose中的Shader实现一个雪花飘飘弹窗效果
android·kotlin·android jetpack
刘龙超5 天前
如何应对 Android 面试官 -> 运用 Jetpack 写一个音乐播放器(四)登录注册
android jetpack
刘龙超7 天前
如何应对 Android 面试官 -> 运用 Jetpack 写一个音乐播放器(三)播放能力
android jetpack
我命由我123458 天前
Android 开发问题:The specified child already has a parent.
android·java·开发语言·java-ee·android jetpack·android-studio·android runtime
Wgllss10 天前
完整案例:Kotlin+Compose+Multiplatform之桌面端音乐播放器,数据库使用实现(三)
android·架构·android jetpack
木子予彤11 天前
Compose 手势处理全面解析
android jetpack