美文网首页
Android 动态换肤 MXSKinChange

Android 动态换肤 MXSKinChange

作者: 仙大 | 来源:发表于2021-08-20 10:33 被阅读0次

    MXSkinChange 动态换肤插件

    项目源码:https://gitee.com/zhangmengxiong/MXSkinChange

    Gradle引用:

        implementation 'com.gitee.zhangmengxiong:MXSkinChange:1.0.6'
    

    插件深度绑定 AppCompatActivity Lifecycle,Activity打开和结束自动释放对View的引用
    项目原理:
    使用 LayoutInflaterCompat.setFactory2(layoutInflater, factory) 方法,对Activity创建View的过程进行注入,对系统View/ViewGroup替换为自定义View/ViewGroup,自定义View会对相关的资源引用进行资源名替换引用

    用法

    1:Application 中需要初始化一次

    MXSkinManager.init(this)
    

    2:在Activity中绑定Factory

    override fun onCreate(savedInstanceState: Bundle?) {
        MXSkinManager.attach(lifecycle, layoutInflater)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
    

    3:定义新皮肤资源文件

    这里假设皮肤名称:dark

    • 在主工程 src/main 新建资源目录 res-dark
    • build.gradle中创建引用新资源目录
    android {
        sourceSets {
            main {
                res.srcDirs = ['src/main/res', 'src/main/res-dark']
            }
        }
    }
    
    • 新资源目录中定义相关资源,新皮肤的所有资源需要加上后缀 _dark
      示例:
      R.drawable.bg_launch_btn -> R.drawable.bg_launch_btn _dark

      R.color.color_red_text -> R.color.color_red_text _dark

    • 加载新皮肤

    // 加载新皮肤 :dark
    MXSkinManager.loadSkin("dark")
    
    // 恢复默认皮肤:
    MXSkinManager.resetSkin()
    

    如何适配自定义View

    插件并不能识别自定义的View,需要手动注入或继承自相对应的View

    如何自定义一个继承自系统View的自定义View

    • 如:LinearLayout/RelativeLayout/FrameLayout/TextView/ImageView/****
    • 自定义View可以继承 MXSkin+xxx 类,

    示例:自定义一个继承自LinearLayout的View,只需要继承自 MXSkinLinearLayout 就可以

    class ColorLinearLayout @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null
    ) : MXSkinLinearLayout(context, attrs) {
        init {
            LayoutInflater.from(context).inflate(R.layout.layout_color, this, true)
        }
        
        *****
        
        // 返回TRUE时,皮肤变更时会刷新这个View的相关资源引用
        override fun needObserved(): Boolean  = true
    }
    

    类似 MXSkinLinearLayout 的View还有:

    • MXSkinLinearLayout::class.java
    • MXSkinRelativeLayout::class.java
    • MXSkinFrameLayout::class.java
    • MXSkinTextView::class.java
    • MXSkinImageView::class.java
    • MXSkinView::class.java
    • MXSkinButton::class.java
    • MXSkinScrollView::class.java
    • MXSkinHorizontalScrollView::class.java
    • MXSkinEditText::class.java
    • MXSkinRadioButton::class.java
    • MXSkinRadioGroup::class.java
    • MXSkinCheckBox::class.java
    • MXSkinCheckTextView::class.java
    • MXSkinProgressBar::class.java
    • MXSkinRatingBar::class.java
    • MXSkinSeekBar::class.java
    • MXSkinViewGroup::class.java
    • MXSkinCardView::class.java
    • MXSkinConstraintLayout::class.java
    • MXSkinRecyclerView::class.java

    如何自定义一个第三方View

    • 先定义一个View
    class CView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null
    ) : androidx.appcompat.widget.AppCompatTextView(context, attrs), ISkinView {
        private var colorResId = BaseAttr.INVALID_ID
    
        init {
            val a: TypedArray = context.obtainStyledAttributes(
                attrs,
                R.styleable.CView,
                0, 0
            )
            try {
                colorResId = BaseAttr.getResourceId(a, R.styleable.CView_color)
            } finally {
                a.recycle()
            }
    
            onSkinChange()
        }
    
        override fun getName(): String {
            // 这里返回这个View在xml中定义的名字
            return CView::class.java.name
        }
    
        override fun getSelfView(): View {
            return this
        }
    
        override fun onSkinChange() {
            // 皮肤更新
            if (colorResId != BaseAttr.INVALID_ID) {
                val color = MXSkinResource.getColorStateList(context, colorResId)
                setTextColor(color)
            }
        }
    }
    
    • 注册这个View
      注意:需要在MXSkinManager.attach(lifecycle, layoutInflater)前进行注册,否则无法识别
    MXSkinViewRegister.register(CView::class.java)
    
    • 调用MXSkinManager.loadSkin("dark")换肤完成

    相关文章

      网友评论

          本文标题:Android 动态换肤 MXSKinChange

          本文链接:https://www.haomeiwen.com/subject/xqxtiltx.html