最近定义了很多Preference,实在话这块儿挺大的,谷歌给的那套不合适基本上就得自己重写一套layout,有时候只是写layout倒是也没什么,就是还有时候要加点高级布局。
一般定义Preference有两种,一种是无二级页面,仅展示title summery或者开关,这种比较好处理。还有一种是带二级页面的,比如点击后弹出一个弹窗,弹窗上的内容也比较高级或者复杂,这种一般写起来也复杂。这里大概总结下,但不贴全。
普通条目Preference
对于普通的SwitchPreference等,继承Preference,将固定的几个layout id对上即可。
简单步骤:
class CustomPreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) { private var initialValue: String? = null init { //界面显示的UI布局 layoutResource = R.layout.preference_layout //跳转的fragment //fragment = NewFragment.Fragment::class.java.name //需要携带的数据 //extras["key"] = "value" } override fun onGetDefaultValue(a: TypedArray, index: Int): Any? { return a.getString(index) } override fun onSetInitialValue(defaultValue: Any?) { initialValue = getPersistedString(defaultValue as? String) } override fun onAttached() { super.onAttached() summary = getPersistedString(initialValue) } }
initialValue就是根据key获取的一个数据,配合defaultValue使用,然后其次一般在onAttached时才进行summary的赋值,这里可以配合自定义的layout中的其他控件去填充数据。这里demo只是string类型,也可以是其他类型,把getPersistedString改了就行。
存在二级弹窗的Preference
首先要让这个首选项所在的fragment支持自定义,也就是说需要先处理PreferenceFragmentCompat,然后大概思路就是重写PreferenceFragmentCompat的onDisplayPreferenceDialog方法,大致如下:
override fun onDisplayPreferenceDialog(preference: Preference) { if (preference is IBaseDialogPreference) { preference.displayPreferenceDialog(this) } else { super.onDisplayPreferenceDialog(preference) } }
这里有两个未知的东西IBaseDialogPreference、preference.displayPreferenceDialog,其实容易理解,因为并没什么合适的方式直接定义DialogPreference,而且其中还有很多麻烦,倒不如自己实现一套方案去显示我们自定义的fragment/dialog。
下一步就知道了,意思是我们的DialogPreference需要实现一个接口IBaseDialogPreference,并实现其displayPreferenceDialog方法,接口如下:
interface IBaseDialogPreference {
fun displayPreferenceDialog(fragment: PreferenceFragmentCompat)
}
类如下:
abstract class BaseDialogPreference(context: Context, attrs: AttributeSet? = null) : DialogPreference(context, attrs), IBaseDialogPreference { abstract fun onCreateDialogFragment(): PreferenceDialogFragmentCompat override fun displayPreferenceDialog(fragment: PreferenceFragmentCompat) { val df = onCreateDialogFragment() if (df.arguments == null) { df.arguments = Bundle() } df.arguments?.putString(ARG_KEY, key) df.setTargetFragment(fragment, 0) df.show(fragment.fragmentManager, "dialog.fragment.$key") } }
然后大概就清晰了,去写个继承PreferenceDialogFragmentCompat的fragment即可。
Tips:
对于二级preference,其实还有更简单的办法,就是将preference的点击事件直接换成显示fragment即可,不需要继承也不需要封装。只需要做fragment的状态定义。(记得自己写key value的保存)
本站由以下主机服务商提供服务支持:
0条评论