CoderAlee / PaintedSkin

一款解决Android App 换肤框架,极低的侵入性与学习成本。
Apache License 2.0
166 stars 23 forks source link

TabLayout的文本颜色和指示器不支持 #51

Closed HitaoLin closed 1 month ago

HitaoLin commented 1 month ago

1726014753741 非常感谢您的回复! 根据您上次的回复做了尝试,发现还是并未能解决问题。 代码如下 //布局代码 <com.google.android.material.tabs.TabLayout android:id="@+id/tab_signal" android:layout_width="wrap_content" android:layout_height="wrap_content" app:tabRippleColor="@color/transparent" app:tabPaddingTop="-20dp" android:layout_gravity="center_vertical" android:layout_marginTop="8dp" />

`//代码文件TabLayoutCompat.kt

import android.content.Context import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.View import com.google.android.material.tabs.TabLayout import org.alee.component.skin.executor.ISkinExecutor import org.alee.component.skin.executor.SkinElement import org.alee.component.skin.executor.ViewSkinExecutor import org.alee.component.skin.factory2.IExpandedFactory2 import org.alee.component.skin.parser.IThemeSkinExecutorBuilder import org.alee.component.skin.service.ThemeSkinService

internal fun tabLayoutCompatible() { //FIXME 第三方View、自定义View 需要添加适配器。否则换肤框架无法创建View实例 ThemeSkinService.getInstance().createViewInterceptor.add(TabLayoutFactory()) // FIXME 第三方View、自定义View 的自定义属性如果需要换肤,需要由使用者通过实现IThemeSkinExecutorBuilder 为框架提供自己的换肤执行器 ThemeSkinService.getInstance().addThemeSkinExecutorBuilder(TabLayoutSkinExecutorBuilder()) }

private class TabLayoutFactory : IExpandedFactory2 {

private companion object { /**

// 创建View

override fun onCreateView( originalView: View?, parent: View?, name: String, context: Context, attrs: AttributeSet ): View? { return if (CLASS_NAME == name) TabLayout(context, attrs) else originalView } }

//自定义View 自定义属性换肤执行器

private class TabLayoutSkinExecutor(fullElement: SkinElement) : ViewSkinExecutor(fullElement) {

override fun applyDrawable(view: TabLayout, drawable: Drawable, attrName: String) { super.applyDrawable(view, drawable, attrName) when (attrName) { TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_INDICATOR -> view.setSelectedTabIndicator(drawable) } }

override fun applyColor(view: TabLayout, colorStateList: ColorStateList, attrName: String) { super.applyColor(view, colorStateList, attrName) when(attrName){ TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_SELECTED_TEXT_COLOR -> view.tabTextColors = colorStateList TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_TEXT_COLOR -> view.tabTextColors = colorStateList } } }

//自定义View换肤执行器构建者 internal class TabLayoutSkinExecutorBuilder : IThemeSkinExecutorBuilder {

internal companion object { /**

/**

/**

/**

CoderAlee commented 1 month ago

1726014753741 非常感谢您的回复! 根据您上次的回复做了尝试,发现还是并未能解决问题。 代码如下 //布局代码 <com.google.android.material.tabs.TabLayout android:id="@+id/tab_signal" android:layout_width="wrap_content" android:layout_height="wrap_content" app:tabRippleColor="@color/transparent" app:tabPaddingTop="-20dp" android:layout_gravity="center_vertical" android:layout_marginTop="8dp" />

`//代码文件TabLayoutCompat.kt

import android.content.Context import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.View import com.google.android.material.tabs.TabLayout import org.alee.component.skin.executor.ISkinExecutor import org.alee.component.skin.executor.SkinElement import org.alee.component.skin.executor.ViewSkinExecutor import org.alee.component.skin.factory2.IExpandedFactory2 import org.alee.component.skin.parser.IThemeSkinExecutorBuilder import org.alee.component.skin.service.ThemeSkinService

internal fun tabLayoutCompatible() { //FIXME 第三方View、自定义View 需要添加适配器。否则换肤框架无法创建View实例 ThemeSkinService.getInstance().createViewInterceptor.add(TabLayoutFactory()) // FIXME 第三方View、自定义View 的自定义属性如果需要换肤,需要由使用者通过实现IThemeSkinExecutorBuilder 为框架提供自己的换肤执行器 ThemeSkinService.getInstance().addThemeSkinExecutorBuilder(TabLayoutSkinExecutorBuilder()) }

private class TabLayoutFactory : IExpandedFactory2 {

private companion object { /* [CustomView] 类名 */ private val CLASS_NAME = TabLayout::class.java.name }

// 创建View

override fun onCreateView( originalView: View?, parent: View?, name: String, context: Context, attrs: AttributeSet ): View? { return if (CLASS_NAME == name) TabLayout(context, attrs) else originalView } }

//自定义View 自定义属性换肤执行器

private class TabLayoutSkinExecutor(fullElement: SkinElement) : ViewSkinExecutor(fullElement) {

override fun applyDrawable(view: TabLayout, drawable: Drawable, attrName: String) { super.applyDrawable(view, drawable, attrName) when (attrName) { TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_INDICATOR -> view.setSelectedTabIndicator(drawable) } }

override fun applyColor(view: TabLayout, colorStateList: ColorStateList, attrName: String) { super.applyColor(view, colorStateList, attrName) when(attrName){ TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_SELECTED_TEXT_COLOR -> view.tabTextColors = colorStateList TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_TEXT_COLOR -> view.tabTextColors = colorStateList } } }

//自定义View换肤执行器构建者 internal class TabLayoutSkinExecutorBuilder : IThemeSkinExecutorBuilder {

internal companion object { /* 底部滑块 */ internal const val ATTRIBUTE_TAB_INDICATOR = "tabIndicator"

/**
 * 选中文本颜色
 */
internal const val ATTRIBUTE_TAB_SELECTED_TEXT_COLOR = "tabSelectedTextColor"

/**
 * 未选中文本颜色
 */
internal const val ATTRIBUTE_TAB_TEXT_COLOR = "tabTextColor"

private val SUPPORT_ATTR: Map<Int, String> = HashMap<Int, String>().apply {
    put(com.google.android.material.R.styleable.TabLayout_tabIndicator, ATTRIBUTE_TAB_INDICATOR)
    put(com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor, ATTRIBUTE_TAB_SELECTED_TEXT_COLOR)
    put(com.google.android.material.R.styleable.TabLayout_tabTextColor, ATTRIBUTE_TAB_TEXT_COLOR)
}

}

/**

  • 解析支持换肤的属性 */ override fun parse(context: Context, attributeSet: AttributeSet): MutableSet? { val typedArray = context.obtainStyledAttributes(attributeSet, com.google.android.material.R.styleable.TabLayout) val elementSet: MutableSet = HashSet() try { for (key in SUPPORT_ATTR.keys) { // FIXME 此处的try catch 是为了避免由于一个属性解析失败导致所有属性都无法换肤 try { if (typedArray.hasValue(key)) { SUPPORT_ATTR[key]?.run { // FIXME 此处代码与addEnabledThemeSkinView 函数一样,需要提供待换肤的属性名称与所使用的资源id给框架 elementSet.add(SkinElement(this, typedArray.getResourceId(key, -1))) } } } catch (ignored: Throwable) { } } } catch (ignored: Throwable) { } finally { typedArray.recycle() } return elementSet }

/**

  • 需要换肤执行器 */ override fun requireSkinExecutor(view: View, element: SkinElement): ISkinExecutor { return TabLayoutSkinExecutor(element) }

/**

  • 是否支持属性 */ override fun isSupportAttr(view: View, attrName: String): Boolean { // FIXME 避免不同View 相同的自定义属性导致处理异常 if (view !is TabLayout) { return false } return SUPPORT_ATTR.containsValue(attrName) } }`

看代码,你是想对 com.google.android.material.R.styleable.TabLayout_tabIndicator com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor com.google.android.material.R.styleable.TabLayout_tabTextColor 这三个属性进行换肤,但在XML中声明TabLayout时,您未对这三个属性设置对应的资源。 可以尝试在tablayout中声明这三个属性: <com.google.android.material.tabs.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/tips_restrict_policy_rv_bg" app:tabIndicator="@drawable/layer_tab_indicator" app:tabIndicatorColor="@color/tips_restrict_policy_indicator_bg" app:tabIndicatorFullWidth="false" app:tabMode="fixed" app:tabSelectedTextColor="@color/tips_restrict_policy_title_selector_color" app:tabTextAppearance="@style/text.Body1.Bold" app:tabTextColor="@color/selector_primary_tab_color" />

HitaoLin commented 1 month ago

您好,您描述的,我已经尝试过,tabIndicator并不能改变,tab的文本都是显示选中的颜色,但切换主题是可以改变的。

------------------ 原始邮件 ------------------ 发件人: "Liu @.>; 发送时间: 2024年9月11日(星期三) 晚上6:14 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [CoderAlee/PaintedSkin] TabLayout的文本颜色和指示器不支持 (Issue #51)

非常感谢您的回复! 根据您上次的回复做了尝试,发现还是并未能解决问题。 代码如下 //布局代码 <com.google.android.material.tabs.TabLayout android:id="@+id/tab_signal" android:layout_width="wrap_content" android:layout_height="wrap_content" @.***/transparent" app:tabPaddingTop="-20dp" android:layout_gravity="center_vertical" android:layout_marginTop="8dp" />

`//代码文件TabLayoutCompat.kt

import android.content.Context import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.View import com.google.android.material.tabs.TabLayout import org.alee.component.skin.executor.ISkinExecutor import org.alee.component.skin.executor.SkinElement import org.alee.component.skin.executor.ViewSkinExecutor import org.alee.component.skin.factory2.IExpandedFactory2 import org.alee.component.skin.parser.IThemeSkinExecutorBuilder import org.alee.component.skin.service.ThemeSkinService

internal fun tabLayoutCompatible() { //FIXME 第三方View、自定义View 需要添加适配器。否则换肤框架无法创建View实例 ThemeSkinService.getInstance().createViewInterceptor.add(TabLayoutFactory()) // FIXME 第三方View、自定义View 的自定义属性如果需要换肤,需要由使用者通过实现IThemeSkinExecutorBuilder 为框架提供自己的换肤执行器 ThemeSkinService.getInstance().addThemeSkinExecutorBuilder(TabLayoutSkinExecutorBuilder()) }

private class TabLayoutFactory : IExpandedFactory2 {

private companion object { /* [CustomView] 类名 */ private val CLASS_NAME = TabLayout::class.java.name }

// 创建View

override fun onCreateView( originalView: View?, parent: View?, name: String, context: Context, attrs: AttributeSet ): View? { return if (CLASS_NAME == name) TabLayout(context, attrs) else originalView } }

//自定义View 自定义属性换肤执行器

private class TabLayoutSkinExecutor(fullElement: SkinElement) : ViewSkinExecutor(fullElement) {

override fun applyDrawable(view: TabLayout, drawable: Drawable, attrName: String) { super.applyDrawable(view, drawable, attrName) when (attrName) { TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_INDICATOR -> view.setSelectedTabIndicator(drawable) } }

override fun applyColor(view: TabLayout, colorStateList: ColorStateList, attrName: String) { super.applyColor(view, colorStateList, attrName) when(attrName){ TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_SELECTED_TEXT_COLOR -> view.tabTextColors = colorStateList TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_TEXT_COLOR -> view.tabTextColors = colorStateList } } }

//自定义View换肤执行器构建者 internal class TabLayoutSkinExecutorBuilder : IThemeSkinExecutorBuilder {

internal companion object { / 底部滑块 / internal const val ATTRIBUTE_TAB_INDICATOR = "tabIndicator" / 选中文本颜色 / internal const val ATTRIBUTE_TAB_SELECTED_TEXT_COLOR = "tabSelectedTextColor" /* 未选中文本颜色 */ internal const val ATTRIBUTE_TAB_TEXT_COLOR = "tabTextColor" private val SUPPORT_ATTR: Map<Int, String> = HashMap<Int, String>().apply { put(com.google.android.material.R.styleable.TabLayout_tabIndicator, ATTRIBUTE_TAB_INDICATOR) put(com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor, ATTRIBUTE_TAB_SELECTED_TEXT_COLOR) put(com.google.android.material.R.styleable.TabLayout_tabTextColor, ATTRIBUTE_TAB_TEXT_COLOR) }
}

/**

解析支持换肤的属性 */ override fun parse(context: Context, attributeSet: AttributeSet): MutableSet? { val typedArray = context.obtainStyledAttributes(attributeSet, com.google.android.material.R.styleable.TabLayout) val elementSet: MutableSet = HashSet() try { for (key in SUPPORT_ATTR.keys) { // FIXME 此处的try catch 是为了避免由于一个属性解析失败导致所有属性都无法换肤 try { if (typedArray.hasValue(key)) { SUPPORT_ATTR[key]?.run { // FIXME 此处代码与addEnabledThemeSkinView 函数一样,需要提供待换肤的属性名称与所使用的资源id给框架 elementSet.add(SkinElement(this, typedArray.getResourceId(key, -1))) } } } catch (ignored: Throwable) { } } } catch (ignored: Throwable) { } finally { typedArray.recycle() } return elementSet }

/**

需要换肤执行器 */ override fun requireSkinExecutor(view: View, element: SkinElement): ISkinExecutor { return TabLayoutSkinExecutor(element) }

/**

是否支持属性 */ override fun isSupportAttr(view: View, attrName: String): Boolean { // FIXME 避免不同View 相同的自定义属性导致处理异常 if (view !is TabLayout) { return false } return SUPPORT_ATTR.containsValue(attrName) } }`

看代码,你是想对 com.google.android.material.R.styleable.TabLayout_tabIndicator com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor com.google.android.material.R.styleable.TabLayout_tabTextColor 这三个属性进行换肤,但在XML中声明TabLayout时,您未对这三个属性设置对应的资源。 可以尝试在tablayout中声明这三个属性: <com.google.android.material.tabs.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" @./tips_restrict_policy_rv_bg" @./layer_tab_indicator" @./tips_restrict_policy_indicator_bg" app:tabIndicatorFullWidth="false" app:tabMode="fixed" @./tips_restrict_policy_title_selector_color" @./text.Body1.Bold" @./selector_primary_tab_color" />

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

CoderAlee commented 1 month ago

https://github.com/user-attachments/assets/92a40730-2364-4daf-995f-38d691628ff8

你是要实现这个效果么?

CoderAlee commented 1 month ago

image image

CoderAlee commented 1 month ago

您好,您描述的,我已经尝试过,tabIndicator并不能改变,tab的文本都是显示选中的颜色,但切换主题是可以改变的。 ------------------ 原始邮件 ------------------ 发件人: "Liu @.>; 发送时间: 2024年9月11日(星期三) 晚上6:14 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [CoderAlee/PaintedSkin] TabLayout的文本颜色和指示器不支持 (Issue #51) 非常感谢您的回复! 根据您上次的回复做了尝试,发现还是并未能解决问题。 代码如下 //布局代码 <com.google.android.material.tabs.TabLayout android:id="@+id/tab_signal" android:layout_width="wrap_content" android:layout_height="wrap_content" @.*/transparent" app:tabPaddingTop="-20dp" android:layout_gravity="center_vertical" android:layout_marginTop="8dp" /> `//代码文件TabLayoutCompat.kt import android.content.Context import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.View import com.google.android.material.tabs.TabLayout import org.alee.component.skin.executor.ISkinExecutor import org.alee.component.skin.executor.SkinElement import org.alee.component.skin.executor.ViewSkinExecutor import org.alee.component.skin.factory2.IExpandedFactory2 import org.alee.component.skin.parser.IThemeSkinExecutorBuilder import org.alee.component.skin.service.ThemeSkinService internal fun tabLayoutCompatible() { //FIXME 第三方View、自定义View 需要添加适配器。否则换肤框架无法创建View实例 ThemeSkinService.getInstance().createViewInterceptor.add(TabLayoutFactory()) // FIXME 第三方View、自定义View 的自定义属性如果需要换肤,需要由使用者通过实现IThemeSkinExecutorBuilder 为框架提供自己的换肤执行器 ThemeSkinService.getInstance().addThemeSkinExecutorBuilder(TabLayoutSkinExecutorBuilder()) } private class TabLayoutFactory : IExpandedFactory2 { private companion object { / [CustomView] 类名 / private val CLASS_NAME = TabLayout::class.java.name } // 创建View override fun onCreateView( originalView: View?, parent: View?, name: String, context: Context, attrs: AttributeSet ): View? { return if (CLASS_NAME == name) TabLayout(context, attrs) else originalView } } //自定义View 自定义属性换肤执行器 private class TabLayoutSkinExecutor(fullElement: SkinElement) : ViewSkinExecutor(fullElement) { override fun applyDrawable(view: TabLayout, drawable: Drawable, attrName: String) { super.applyDrawable(view, drawable, attrName) when (attrName) { TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_INDICATOR -> view.setSelectedTabIndicator(drawable) } } override fun applyColor(view: TabLayout, colorStateList: ColorStateList, attrName: String) { super.applyColor(view, colorStateList, attrName) when(attrName){ TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_SELECTED_TEXT_COLOR -> view.tabTextColors = colorStateList TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_TEXT_COLOR -> view.tabTextColors = colorStateList } } } //自定义View换肤执行器构建者 internal class TabLayoutSkinExecutorBuilder : IThemeSkinExecutorBuilder { internal companion object { / 底部滑块 / internal const val ATTRIBUTE_TAB_INDICATOR = "tabIndicator" / 选中文本颜色 / internal const val ATTRIBUTE_TAB_SELECTED_TEXT_COLOR = "tabSelectedTextColor" / 未选中文本颜色 / internal const val ATTRIBUTE_TAB_TEXT_COLOR = "tabTextColor" private val SUPPORT_ATTR: Map<Int, String> = HashMap<Int, String>().apply { put(com.google.android.material.R.styleable.TabLayout_tabIndicator, ATTRIBUTE_TAB_INDICATOR) put(com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor, ATTRIBUTE_TAB_SELECTED_TEXT_COLOR) put(com.google.android.material.R.styleable.TabLayout_tabTextColor, ATTRIBUTE_TAB_TEXT_COLOR) } } /* 解析支持换肤的属性 / override fun parse(context: Context, attributeSet: AttributeSet): MutableSet? { val typedArray = context.obtainStyledAttributes(attributeSet, com.google.android.material.R.styleable.TabLayout) val elementSet: MutableSet = HashSet() try { for (key in SUPPORT_ATTR.keys) { // FIXME 此处的try catch 是为了避免由于一个属性解析失败导致所有属性都无法换肤 try { if (typedArray.hasValue(key)) { SUPPORT_ATTR[key]?.run { // FIXME 此处代码与addEnabledThemeSkinView 函数一样,需要提供待换肤的属性名称与所使用的资源id给框架 elementSet.add(SkinElement(this, typedArray.getResourceId(key, -1))) } } } catch (ignored: Throwable) { } } } catch (ignored: Throwable) { } finally { typedArray.recycle() } return elementSet } / 需要换肤执行器 */ override fun requireSkinExecutor(view: View, element: SkinElement): ISkinExecutor { return TabLayoutSkinExecutor(element) } / 是否支持属性 / override fun isSupportAttr(view: View, attrName: String): Boolean { // FIXME 避免不同View 相同的自定义属性导致处理异常 if (view !is TabLayout) { return false } return SUPPORT_ATTR.containsValue(attrName) } }` 看代码,你是想对 com.google.android.material.R.styleable.TabLayout_tabIndicator com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor com.google.android.material.R.styleable.TabLayout_tabTextColor 这三个属性进行换肤,但在XML中声明TabLayout时,您未对这三个属性设置对应的资源。 可以尝试在tablayout中声明这三个属性: <com.google.android.material.tabs.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" @./tips_restrict_policy_rv_bg" @./layer_tab_indicator" @./tips_restrict_policy_indicator_bg" app:tabIndicatorFullWidth="false" app:tabMode="fixed" @./tips_restrict_policy_title_selector_color" @./text.Body1.Bold" @./selector_primary_tab_color" /> — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.>

`package org.alee.demo.skin.basic.ability.tab

import android.content.Context import android.content.res.ColorStateList import android.util.AttributeSet import android.view.View import androidx.core.content.res.use import com.google.android.material.tabs.TabLayout import org.alee.component.skin.executor.ISkinExecutor import org.alee.component.skin.executor.SkinElement import org.alee.component.skin.executor.ViewSkinExecutor import org.alee.component.skin.parser.IThemeSkinExecutorBuilder import org.alee.component.skin.service.ThemeSkinService import org.alee.demo.skin.basic.ability.R

internal fun tabLayoutCompatible() { ThemeSkinService.getInstance().addThemeSkinExecutorBuilder(TabLayoutSkinExecutorBuilder()) }

private class TabLayoutSkinExecutor( fullElement: SkinElement, ) : ViewSkinExecutor(fullElement) { override fun applyColor( view: TabLayout, color: Int, attrName: String, ) { super.applyColor(view, color, attrName) when (attrName) { TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_INDICATOR_COLOR -> view.setSelectedTabIndicatorColor(color) TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_SELECTED_TEXT_COLOR, TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_TEXT_COLOR, -> applyColor(view, ColorStateList.valueOf(color), attrName) } }

override fun applyColor(
    view: TabLayout,
    colorStateList: ColorStateList,
    attrName: String,
) {
    super.applyColor(view, colorStateList, attrName)
    when (attrName) {
        TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_INDICATOR_COLOR -> applyColor(view, colorStateList.defaultColor, attrName)
        TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_SELECTED_TEXT_COLOR -> {
            val originalTabTextColor = view.tabTextColors?.getColorForState(intArrayOf(1), colorStateList.defaultColor)
            view.setTabTextColors(originalTabTextColor ?: colorStateList.defaultColor, colorStateList.defaultColor)
        }

        TabLayoutSkinExecutorBuilder.ATTRIBUTE_TAB_TEXT_COLOR -> {
            val originalTabSelectedTextColor = view.tabTextColors?.getColorForState(intArrayOf(0), colorStateList.defaultColor)
            view.setTabTextColors(colorStateList.defaultColor, originalTabSelectedTextColor ?: colorStateList.defaultColor)
        }
    }
}

}

private class TabLayoutSkinExecutorBuilder : IThemeSkinExecutorBuilder { companion object { internal const val ATTRIBUTE_TAB_INDICATOR_COLOR = "tabIndicatorColor" internal const val ATTRIBUTE_TAB_SELECTED_TEXT_COLOR = "tabSelectedTextColor" internal const val ATTRIBUTE_TAB_TEXT_COLOR = "tabTextColor"

    private val SUPPORT_ATTR: Map<Int, String> =
        HashMap<Int, String>(3).apply {
            put(R.styleable.TabLayout_tabIndicatorColor, ATTRIBUTE_TAB_INDICATOR_COLOR)
            put(R.styleable.TabLayout_tabSelectedTextColor, ATTRIBUTE_TAB_SELECTED_TEXT_COLOR)
            put(R.styleable.TabLayout_tabTextColor, ATTRIBUTE_TAB_TEXT_COLOR)
        }
}

/**
 * 解析支持换肤的属性
 *
 * @param context      [Context]
 * @param attributeSet [AttributeSet]
 *
 * @return [SkinElement]
 */
override fun parse(
    context: Context,
    attributeSet: AttributeSet,
): MutableSet<SkinElement> =
    context.obtainStyledAttributes(attributeSet, R.styleable.TabLayout).use { typedArray ->
        SUPPORT_ATTR
            .filter {
                typedArray.hasValue(
                    it.key,
                )
            }.map { SkinElement(it.value, typedArray.getResourceId(it.key, -1)) }
            .toMutableSet()
    }

/**
 * 需要换肤执行器
 *
 * @param view    需要换肤的View
 * @param element 需要执行的元素
 *
 * @return [ISkinExecutor]
 */
override fun requireSkinExecutor(
    view: View,
    element: SkinElement,
): ISkinExecutor = TabLayoutSkinExecutor(element)

/**
 * 是否支持属性
 *
 * @param view     View
 * @param attrName 属性名称
 *
 * @return true: 支持
 */
override fun isSupportAttr(
    view: View,
    attrName: String,
): Boolean {
    if (view is TabLayout) {
        return SUPPORT_ATTR.containsValue(attrName)
    }
    return false
}

} `

CoderAlee commented 1 month ago

https://github.com/CoderAlee/PaintedSkin/commit/6081d2fe519b996e95f372fc7fa7c765fb9d770c 最新一笔提交已为TabLayout添加换肤示例,请参考。

HitaoLin commented 1 month ago

感谢您的支持!经过测试没有问题。

HitaoLin commented 1 month ago

感谢您的支持!经过测试没有问题。

------------------ 原始邮件 ------------------ 发件人: "Liu @.>; 发送时间: 2024年9月11日(星期三) 晚上8:59 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [CoderAlee/PaintedSkin] TabLayout的文本颜色和指示器不支持 (Issue #51)

6081d2f 最新一笔提交已为TabLayout添加换肤示例,请参考。

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>