IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android(12)Preference(三)抽象管理 -> 正文阅读

[移动开发]Android(12)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")
        }
    }
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:19:17  更:2022-02-03 01:19:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 13:46:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码