ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-02-01 10:32:20  阅读:250  来源: 互联网

标签:12 String param Preference override Android prefKey preference


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

问题发生背景:

假如我们现在有一个设置页面,虽然我们可以通过获取Preference实例去set一些ClickChange监听,但是当我们的业务逻辑增加并且复杂的时候,会发现我们每次都要先去找到一个实例才能去设置,这个时候就需要分离UI逻辑和数据逻辑了,比如我希望点击的时候只是通过传过来的key判断UI的变化,是跳转到下一个设置页面还是弹出一个对话框等;点击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<String>()
    
        /**
         * 处理UI相关的逻辑
         *
         * @param preference Preference
         * @param prefKey String
         * @return Boolean  是否消费
         */
        abstract fun handleInteractionLogic(preference: Preference, prefKey: String): Boolean
    
        /**
         * 处理数据相关逻辑
         *
         * @param preference Preference
         * @param prefKey String
         */
        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中定义自己的属性
    <resources>
        <attr name="myPreferenceStyle" format="reference"/>
    
        <declare-styleable name="MyPreference">
            <attr name="myPfTitleTextColor" format="color"/>
            <attr name="myPfTitleTextSize" format="dimension"/>
        </declare-styleable>
    </resources>
    
    • theme.xml定义一个style指定myPreferenceStyle,记得<applicatiopn/>themme要指定为我们的哟
    <resources xmlns:tools="http://schemas.android.com/tools">
        <!-- Base application theme. -->
        <style name="Theme.MyApplication" parent="Theme.AppCompat.DayNight.NoActionBar">
            <!-- Primary brand color. -->
            <item name="colorPrimary">@color/purple_500</item>
            <item name="colorPrimaryVariant">@color/purple_700</item>
            <item name="colorOnPrimary">@color/white</item>
            <!-- Secondary brand color. -->
            <item name="colorSecondary">@color/teal_200</item>
            <item name="colorSecondaryVariant">@color/teal_700</item>
            <item name="colorOnSecondary">@color/black</item>
            <!-- Status bar color. -->
            <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
            <!-- Customize your theme here. -->
    
            <item name="myPreferenceStyle">@style/MyPreferenceStyle</item>
        </style>
        
        
        // _-----------------------
    
        // 这里就可以统一设置自己定义的属性拉
        <style name="MyPreferenceStyle">
            <item name="myPfTitleTextColor">#FF4081</item>
            <item name="myPfTitleTextSize">20sp</item>
        </style>
        
        
    
        <style name="CollapsingToolbarTitle.Collapsed" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
            <item name="android:textSize">22sp</item>
            <item name="android:textColor">#FF4081</item>
        </style>
    
        <style name="CollapsingToolbarTitle.Expanded" parent="CollapsingToolbarTitle.Collapsed">
            <item name="android:textSize">36sp</item>
            <item name="android:textColor">#536DFE</item>
        </style>
    </resources>
    
  • 代码里使用属性:

    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

        /**
         * 处理 UI
         * 
         * @param preference Preference
         * @param prefKey String
         * @return Boolean
         */
        override fun handleInteractionLogic(preference: Preference, prefKey: String): Boolean {
            TODO("Not yet implemented")
        }

        /**
         * 处理 数据
         * 
         * @param preference Preference
         * @param prefKey String
         */
        override fun handleDataLogic(preference: Preference, prefKey: String) {
            TODO("Not yet implemented")
        }
    }
}

标签:12,String,param,Preference,override,Android,prefKey,preference
来源: https://blog.csdn.net/C_biubiubiu/article/details/122762930

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有