
假如我们现在有一个设置页面,虽然我们可以通过获取Preference实例去set一些Click、Change监听,但是当我们的业务逻辑增加并且复杂的时候,会发现我们每次都要先去找到一个实例才能去设置,这个时候就需要分离UI逻辑和数据逻辑了,比如我希望点击的时候只是通过传过来的key判断UI的变化,是跳转到下一个设置页面还是d出一个对话框等;点击Switch改变值的时候通过key判断,意思就是把原来的点击处理一票子逻辑拆分成俩部分方便管理。
开始抽象,准备动手!
先抽象出一个PreferenceFragmentCompat容器的Activity。
有对应页面的标题统一风格的背景和Toobar
abstract class baseSettingsActivity: AppCompatActivity() {
// 根Fragment名字
abstract val hostFragmentName: String
protected val activityLayoutRes = R.layout.activity_main
var hostFragment: baseSettingsFragment? = null
// Toolbar相关
protected var actionBar: ActionBar? = null
protected lateinit var toolBar: Toolbar
protected var collapsingToolbarLayout: CollapsingToolbarLayout? = null
protected var appBarLayout: AppBarLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(activityLayoutRes)
// 设置协调布局和toolbar
toolBar = findViewById(R.id.toolbar)
setSupportActionBar(toolBar)
actionBar = supportActionBar
actionBar?.let {
it.setDisplayHomeAsUpEnabled(true)
it.setHomeButtonEnabled(true)
it.setDisplayShowTitleEnabled(true)
}
toolBar.apply {
setNavigationOnClickListener {
finishAndRemoveTask()
}
}
collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar)
appBarLayout = findViewById(R.id.appbar_layout)
collapsingToolbarLayout?.let {
it.title = title
}
val fragment = supportFragmentManager.fragmentFactory.instantiate(
this.classLoader,
hostFragmentName
)
hostFragment = fragment as baseSettingsFragment
supportFragmentManager
.beginTransaction()
.replace(
R.id.setting_fragment_container,
fragment
).commit()
}
}
再抽象出一个PreferenceFragmentCompat:
处理UI交互处理数据逻辑
abstract class baseSettingsFragment: PreferenceFragmentCompat() {
// 设置布局资源id
abstract val xmlRes: Int
// 这个页面上可见的Preference的key
val preferenceKeys = mutableListOf()
abstract fun handleInteractionLogic(preference: Preference, prefKey: String): Boolean
abstract fun handleDataLogic(preference: Preference, prefKey: String)
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(xmlRes, rootKey)
}
override fun onPreferenceTreeClick(preference: Preference): Boolean {
return handleInteractionLogic(preference, preference.key)
}
}
搞一个自己的Preference:
在attr.xml中定义自己的属性
在theme.xml定义一个style指定myPreferenceStyle,记得的themme要指定为我们的哟
// _----------------------- // 这里就可以统一设置自己定义的属性拉
代码里使用属性:
class MyPreference(
context: Context,
attributeSet: AttributeSet,
defStyleAttr: Int = R.attr.myPreferenceStyle
): Preference(context, attributeSet, defStyleAttr) {
val hostFragment by lazy {
context.takeIf { it is baseSettingsActivity }?.let {
(it as baseSettingsActivity).hostFragment
}
}
private var titleTextColor = 0
private var titleTextSize = 0f
init {
widgetLayoutResource = R.layout.my_widget
context.obtainStyledAttributes(
attributeSet,
R.styleable.MyPreference, defStyleAttr, 0
).apply {
titleTextColor =
getColor(R.styleable.MyPreference_myPfTitleTextColor, Color.BLACK)
titleTextSize =
getDimension(R.styleable.MyPreference_myPfTitleTextSize, 10f)
recycle()
}
hostFragment.takeIf { it is baseSettingsFragment }?.preferenceKeys?.add(key)
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
with(holder) {
findViewById(android.R.id.title).takeIf { it is TextView }?.let {
(it as TextView).setTextColor(titleTextColor)
it.textSize = titleTextSize
}
}
holder.findViewById(R.id.switchWidget).takeIf { it is Switch }?.let {
(it as Switch).setonCheckedChangeListener { buttonView, isChecked ->
hostFragment?.handleDataLogic(this, key)
}
}
}
}
使用
在搞完通用的之后了,就可以使用了:
class MyActivity: baseSettingsActivity() {
override val hostFragmentName: String
get() = MyFragemnt::class.java.name
class MyFragemnt: baseSettingsFragment() {
override val xmlRes: Int
get() = R.xml.settings
override fun handleInteractionLogic(preference: Preference, prefKey: String): Boolean {
TODO("Not yet implemented")
}
override fun handleDataLogic(preference: Preference, prefKey: String) {
TODO("Not yet implemented")
}
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)