根据主题不同,引用不同的资源文件

Posted 爱吃烧鸡大肘子的肉肉酱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据主题不同,引用不同的资源文件相关的知识,希望对你有一定的参考价值。

在开发中,一款APP会设置几款皮肤,也就会涉及到资源文件的引用问题。

现在来摸鱼记录一下吧。

一、首先建立几个style,也就是我们的皮肤style。比如:

<style name="ClassicTneme" parent="Theme.MaterialComponents.Light.NoActionBar">
        <item name="android:windowIsTranslucent">true</item>
        <item name="colorPrimary">@color/primaryColor_theme1</item>
        <item name="colorOnPrimary">#fafafa</item>
        <item name="colorPrimaryDark">@color/primaryDarkColor_theme1</item>
        <item name="colorPrimaryVariant">@color/primaryDarkColor_theme1</item>
        <item name="colorSecondary">@color/secondaryColor_theme1</item>
        <item name="colorSecondaryVariant">@color/secondaryLightColor_theme1</item>
        <item name="colorOnSecondary">#fafafa</item>
        <item name="android:textColor">#181818</item>
        <item name="colorSurface">#ffffff</item>
        <item name="colorOnSurface">#000000</item>
        <item name="colorError">#ff0000</item>
        <item name="actionModeBackground">@color/secondaryColor_theme1</item>
        <item name="actionModeCloseDrawable">@null</item>

    </style>
<style name="AppTheme2" parent="Theme.MaterialComponents.Light.NoActionBar">
        <item name="colorPrimary">@color/primaryColor_theme2</item>
        <item name= "colorPrimaryDark">@color/primaryDarkColor_theme2</item>
        <item name="colorPrimaryVariant">@color/primaryDarkColor_theme2</item>
        <item name="colorSecondary">@color/secondaryColor_theme2</item>
        <item name="colorSecondaryVariant">@color/secondaryLightColor_theme2</item>

        <item name="colorOnPrimary">#ffffff</item>
        <item name="colorOnSecondary">#fafafa</item>
        <item name="android:textColor">#181818</item>
        <item name="colorSurface">#ffffff</item>
        <item name="colorOnSurface">#000000</item>
        <item name="colorError">#ff0000</item>
        <item name="actionModeBackground">@color/secondaryColor_theme2</item>
        <item name="actionModeCloseDrawable">@null</item>


    </style>

可以看到,这两款风格都有相同name的item,它们在不同的风格下的设置不同,当然对于图片资源也可以使用这种方式来配置,但是当图片资源过多的时候,每个风格下面都需要建立一个同名item,然后将这个item值分别设置为这两张图片,这样配置就很麻烦了,而且在新增资源文件的时候,需要在每个风格下配置,也很麻烦呢。

这种情况下,可以采用某种规律对图片进行命名,然后定义一套基于主题来搜索图片的方法就可以啦。比如,界面在两种风格下分别引用的是图片A,图片B。那么我们可以对图片A命名为icon_background_theme1,icon_background_theme2.这样我们在引用文件的时候,直接传入icon_background_theme1,根据当前设置的主题来对引用的资源名进行剪切拼接,从而获取我们想要的资源名称或者id。

这个时候就需要写一个这样的工具类啦。

public class ThemeUtil 
    private static String sThemeValue = "1";
    private static int sTheme = R.style.ClassicTneme;
    private static ContextThemeWrapper contextThemeWrapper;

    
    public static void initTheme(Application context) 
        LocalSharePara localSharePara = new LocalSharePara(context.getSharedPreferences("localShare", MODE_PRIVATE));
        sThemeValue = localSharePara.getThemeStyle();
        if (sThemeValue.equals("1")) 
            sTheme = R.style.ClassicTneme;
         else if (sThemeValue.equals("2")) 
            sTheme = R.style.AppTheme2;
         else 
            sTheme = R.style.AppTheme3;
        
        contextThemeWrapper = new ContextThemeWrapper(context, sTheme);
    

    
    public static int getTheme() 
        return sTheme;
    
  
    public static int getAttrColor(@AttrRes int attr) 
        TypedValue typedValue = new TypedValue();
        contextThemeWrapper.getTheme().resolveAttribute(attr, typedValue, true);
        return typedValue.data;
    

    @Nullable
    public static Drawable loadThemeDrawable(@DrawableRes int id) 
        Resources resources = Utils.getApp().getResources();
        String defaultName = resources.getResourceEntryName(id);
        return loadThemeDrawable(defaultName);
    
    public static Bitmap loadThemeBitmap(@DrawableRes int id)
        Drawable drawable = loadThemeDrawable(id);
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE? Bitmap.Config.ARGB_8888: Bitmap.Config.RGB_565;
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicWidth());
        drawable.draw(canvas);
        return bitmap;
    


    @SuppressLint("RestrictedApi")
    public static int loadThemeColor(@AttrRes int attrResId)
        return MaterialColors.getColor(contextThemeWrapper,attrResId, Color.BLACK);
    
    @Nullable
    public static Drawable loadThemeDrawable(String defaultName) 
        String name = defaultName.replace("theme1", "theme" + sThemeValue);
        int id = ResourceUtils.getDrawableIdByName(name);
        if (id != 0) 
            return ResourceUtils.getDrawable(id);
        
        return null;
    

    public static int loadThemeDrawableId(@DrawableRes int defaultId) 
        Resources resources = Utils.getApp().getResources();
        String defaultName = resources.getResourceEntryName(defaultId);
        String name = defaultName.replace("theme1", "theme" + sThemeValue);
        int id = ResourceUtils.getDrawableIdByName(name);
        return id;
    

    public static void applyImageViewTheme(ImageView imageView, @DrawableRes int id) 
        Drawable d = loadThemeDrawable(id);
        if (d != null) 
            imageView.setImageDrawable(d);
        
    

然后我们在Java代码中引用资源文件的时候,就通过这个工具类来引用,这不是整挺好么?

整挺好。

以上是关于根据主题不同,引用不同的资源文件的主要内容,如果未能解决你的问题,请参考以下文章

根据主题更改 Drawable

WordPress主题开发:根据不同分类使用不同模板实例

android studio 不同module资源重名引起引用混乱怎么解决?

WPF中的xaml引用不同项目间资源的问题

使用 webpack 的多个引导主题

前端切换主题颜色的几种思路