如何根据 android(dark/light 主题)中的当前应用主题从字符串名称中获取可绘制资源 ID
How to get drawable resource id from string name base on current app theme in android (dark/light theme)
我可以使用以下方法按字符串名称获取资源 ID
fun resIdByName(): Int {
return resources.getIdentifier("apple", "drawable", packageName)
}
但问题是我的应用程序中有 dark/light 情绪支持,此方法为黑暗情绪返回浅色图像,为浅色情绪返回深色图像。
我在互联网上搜索了很多,但只找到了一种从名称中获取资源的方法,而不是如何根据主题获取资源的方法,所以不要认为这是一个重复的问题。
简短回答:不要使用 setImageResource(Int id)。使用 getResources().getDrawable(Int id, Resources.Theme theme) 获取主题可绘制对象并使用 setImageDrawable(Drawable drawable) 代替。
说明:主题资源没有特定的 id suffix/preffix;在所有主题中都是相同的 ID,以避免破坏应用程序。主题应该事先应用,允许所有主题敏感的值被主题的版本替换。通常,视觉上下文 (activity) 包含引用,但根据 how/when 您尝试获取资源的情况,您可能会得到一个具有不同主题的资源(例如,应用程序上下文将没有主题引用),正因为如此,我们从 api 22 开始就有了 getDrawable(Int id, Resources.Theme theme) 。这就是问题的根源。当你调用 setImageDrawable(Int res) 时,imageView 执行这个块:
private void resolveUri() {
if (mDrawable != null) {
return;
}
if (getResources() == null) {
return;
}
Drawable d = null;
if (mResource != 0) {
try {
d = mContext.getDrawable(mResource);
} catch (Exception e) {
Log.w(LOG_TAG, "Unable to find resource: " + mResource, e);
// Don't try again.
mResource = 0;
}
} else if (mUri != null) {
d = getDrawableFromUri(mUri);
if (d == null) {
Log.w(LOG_TAG, "resolveUri failed on bad bitmap uri: " + mUri);
// Don't try again.
mUri = null;
}
} else {
return;
}
updateDrawable(d);
}
如您所见,它使用了已弃用的 Context.getDrawable(Int id) 方法。因此,drawable 最多只能匹配上下文中的主题引用(如果有的话)。在您的小部件中,调用可能发生在其余更改发生之前。因此,请指定所需的主题,这样就没问题了。
我可以使用以下方法按字符串名称获取资源 ID
fun resIdByName(): Int {
return resources.getIdentifier("apple", "drawable", packageName)
}
但问题是我的应用程序中有 dark/light 情绪支持,此方法为黑暗情绪返回浅色图像,为浅色情绪返回深色图像。
我在互联网上搜索了很多,但只找到了一种从名称中获取资源的方法,而不是如何根据主题获取资源的方法,所以不要认为这是一个重复的问题。
简短回答:不要使用 setImageResource(Int id)。使用 getResources().getDrawable(Int id, Resources.Theme theme) 获取主题可绘制对象并使用 setImageDrawable(Drawable drawable) 代替。
说明:主题资源没有特定的 id suffix/preffix;在所有主题中都是相同的 ID,以避免破坏应用程序。主题应该事先应用,允许所有主题敏感的值被主题的版本替换。通常,视觉上下文 (activity) 包含引用,但根据 how/when 您尝试获取资源的情况,您可能会得到一个具有不同主题的资源(例如,应用程序上下文将没有主题引用),正因为如此,我们从 api 22 开始就有了 getDrawable(Int id, Resources.Theme theme) 。这就是问题的根源。当你调用 setImageDrawable(Int res) 时,imageView 执行这个块:
private void resolveUri() {
if (mDrawable != null) {
return;
}
if (getResources() == null) {
return;
}
Drawable d = null;
if (mResource != 0) {
try {
d = mContext.getDrawable(mResource);
} catch (Exception e) {
Log.w(LOG_TAG, "Unable to find resource: " + mResource, e);
// Don't try again.
mResource = 0;
}
} else if (mUri != null) {
d = getDrawableFromUri(mUri);
if (d == null) {
Log.w(LOG_TAG, "resolveUri failed on bad bitmap uri: " + mUri);
// Don't try again.
mUri = null;
}
} else {
return;
}
updateDrawable(d);
}
如您所见,它使用了已弃用的 Context.getDrawable(Int id) 方法。因此,drawable 最多只能匹配上下文中的主题引用(如果有的话)。在您的小部件中,调用可能发生在其余更改发生之前。因此,请指定所需的主题,这样就没问题了。