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

在开发中,一款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代码中引用资源文件的时候,就通过这个工具类来引用,这不是整挺好么?

整挺好。

猜你喜欢

转载自blog.csdn.net/happy0li/article/details/122510974