在 Android 上针对不同的屏幕尺寸和密度重用可绘制图像
Posted
技术标签:
【中文标题】在 Android 上针对不同的屏幕尺寸和密度重用可绘制图像【英文标题】:Reuse drawable images for different screen sizes and densities on Android 【发布时间】:2014-10-02 21:59:43 【问题描述】:背景: 我正在为平板电脑(横向)开发一个具有分辨率为 1920x1200 的图像资源的 android 应用程序。该分辨率适合以下屏幕尺寸和密度:
drawable-xlarge-hdpi
drawable-large-xhdpi
问题: 如果我在这两个文件夹中包含所有复制的图像资源,则 APK 的最终大小将不必要地沉重
我不成功的做法: 我尝试对此处定义的可绘制对象使用别名: http://developer.android.com/guide/topics/resources/providing-resources.html#AliasResources
我的图片资源在:
res/drawable-nodpi/image_cmn.png
以及相应屏幕尺寸和密度文件夹中的两个别名:
res/drawable-xlarge-hdpi/image.xml
res/drawable-large-xhdpi/image.xml
image.xml:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/image_cmn" />
当然,当我在布局文件中使用我的图像时,我会引用别名:
<ImageView
android:layout_
android:layout_
android:src="@drawable/image" />
但遗憾的是,Android 没有为我的测试平板电脑 (mdpi) 正确调整资源大小,结果是我有更大的图像。
我尝试将原始 png 移动到 res/drawable 甚至移动到 res/raw 但结果与 res/drawable-nodpi.
如果我将此 png 移动到 res/drawable-xlarge-hdpi(与 xml 别名相同),结果是正确的,但自然不能解决我的问题,因为我还必须将它们复制到res/drawable-large-xhdpi 和 apk 大小增加。
有人知道如何实现吗?
【问题讨论】:
通常我们只对可绘制资源使用密度限定符。你真的不需要添加 large/xlarge,因为这两个只处理布局资源。(顺便说一句,我从来没有看到它们一起使用) @suitianshi:不,根据屏幕大小设置不同的drawable也是合理的。 Google 在平台中执行此操作,例如,使用res/drawable-sw600dp-hdpi/
等资源目录。
“该分辨率适合以下屏幕尺寸和密度”——1920x1200 与屏幕尺寸几乎没有关系。例如,我希望在今年晚些时候看到-normal
设备运行该分辨率(或更高)。
@CommonsWare 我同意,手机也可以有这个分辨率。在这种情况下,我只需要为平板电脑开发,所以这些是我需要的文件夹
我也有同样的问题,使用别名的时候图片太大了,这种方法对drawables基本上没用......谷歌如何将这种东西发布到生产中?
【参考方案1】:
我尽量避免在 ImageViews 上使用 wrap_content,因为不同的平台版本会以不同的方式调整图像的大小,如果您在 dp 中设置了明确的宽度和高度,则选择哪个图像并不重要。
在你的情况下,我会在 drawable/xhdpi 中有一个图像。在 dp 的布局文件中指定它的宽度和高度。对于 1920x1200 像素的图像,layout_ layout_
x-large 平板电脑上的图片与大型平板电脑的物理尺寸大致相同。
如果您希望图像在 x-large 平板电脑上更大,请包含第二个布局文件,其中增加了图像的宽度和高度,但保留相同的图像。
或者,您可以使用 large 和 x-large 之间不同的维度资源。
【讨论】:
恐怕这将是唯一的解决方案。我一点都不高兴(这个 android 问题),因为这种方法会增加低分辨率设备的内存消耗。 您可以将我的方法与您的方法相结合,使用 xml 别名来选择您想要的图像,然后在布局中使用显式 dp 大小来控制可视化运行时调整大小。 这种方法调整所有图像的大小,使它们变得模糊......这不是一个关于质量的好方法。相反,我试图尽可能多地使用 wrap_content 参数将图像保留为原始大小。但我仍在努力寻找这个话题的解决方案。【参考方案2】:我可以针对这个问题提出两种解决方案:
第一个:
-
将所有图像放入 assets 文件夹。按分辨率将它们拆分到文件夹中。
编写您自己的逻辑以确定当前设备的分辨率和/或大小。
从具有确定分辨率的文件夹中选择图像。
在代码中将其设置为您的
ImageView
。
第二个(很丑,但是很快):
只需使用tinypng.com 压缩您的 png 图像。它可以将您的图像缩小多达 70-80%,而不会降低质量(适用于移动设备)。
【讨论】:
【参考方案3】:这个怎么样:
-
把你所有的图片资源放到
res/drawable-nodpi
将不同的布局文件放入res/layout-xlarge
, res/layout-large
, res/layout
在ImageView
上使用此图像时,不要使用match_parent
或wrap_content
,而是使用计算的dp 大小。
这应该可以,但缺点是它不使用pre-scaling,这意味着在较低 dpi 的设备上,它会消耗更多的内存。
【讨论】:
可能这是唯一的解决方案。但是,Android 怎么可能不考虑到这一点呢?我刚刚打开了一个问题 74825 也许还有另一种解决方法,将图像放入资产中并根据您的设备分辨率和大小手动加载。【参考方案4】:好的,我有你的问题。我有我的话与这个问题有关
有两种方法,我都推荐了。
第一种方式(更方便与您当前的问题相关。)
如果大小变大,请上传多个 apk。
关注official guide。
第二种方式我更喜欢用这种方式。
创建多个布局。如下所示
res/layout/main_activity.xml ---> # 对于handsets(小于600dp可用宽度)
res/layout-sw600dp/main_activity.xml --># 适用于7英寸平板电脑(600dp宽及更大)
res/layout-sw720dp/main_activity.xml # 适用于 10 英寸平板电脑(720dp 宽和更大)
我强烈建议阅读this official doc by google的每一个字。
谢谢。
【讨论】:
【参考方案5】:如果您想为所有尺寸的设备使用相同的图像,那么我认为您必须使用 9-Patch Images。
这里是Android官方文章click here.
之前:
之后:
请参考:Android 9 Patch Image Tutorial
希望对你有帮助。
【讨论】:
这对于可以以具体像素拉伸的简单图像来说是一个很好的解决方案,但对于像照片这样的完整图像则不行【参考方案6】:如果您想为所有尺寸的设备使用相同的图像,那么我认为您应该使用 9 个补丁图像,每个布局在 android 的线性布局内包含权重标签。我认为这是100%的工作。我确定。因为我将这种方法用于通用应用程序(意味着平板电脑和设备应用程序)
【讨论】:
以上是关于在 Android 上针对不同的屏幕尺寸和密度重用可绘制图像的主要内容,如果未能解决你的问题,请参考以下文章