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