Android(12)Preference(三)抽象管理

Android(12)Preference(三)抽象管理,第1张

Android(12)Preference(三)抽象管理 Android(12)Preference(三)抽象管理 问题发生背景:

假如我们现在有一个设置页面,虽然我们可以通过获取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")
        }
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zaji/5719194.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-17
下一篇2022-12-17

发表评论

登录后才能评论

评论列表(0条)

    保存