总结安卓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
       //对控件进行赋值等操作
    }
}
相关推荐
开发者阿伟14 小时前
Android Jetpack DataBinding源码解析与实践
android·android jetpack
alexhilton6 天前
Android技巧:学习使用GridLayout
android·kotlin·android jetpack
Wgllss14 天前
轻松搞定Android蓝牙打印机,双屏异显及副屏分辨率适配解决办法
android·架构·android jetpack
alexhilton20 天前
群星闪耀的大前端开发
android·kotlin·android jetpack
一航jason1 个月前
Android Jetpack Compose 现有Java老项目集成使用compose开发
android·java·android jetpack
帅次1 个月前
Android CoordinatorLayout:打造高效交互界面的利器
android·gradle·android studio·rxjava·android jetpack·androidx·appcompat
IAM四十二1 个月前
Jetpack Compose State 你用对了吗?
android·android jetpack·composer
Wgllss1 个月前
那些大厂架构师是怎样封装网络请求的?
android·架构·android jetpack
x0242 个月前
Android Room(SQLite) too many SQL variables异常
sqlite·安卓·android jetpack·1024程序员节
alexhilton2 个月前
深入理解观察者模式
android·kotlin·android jetpack