在 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/layoutImageView 上使用此图像时,不要使用match_parentwrap_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 上针对不同的屏幕尺寸和密度重用可绘制图像的主要内容,如果未能解决你的问题,请参考以下文章

Android 适配知识点

Android学习路线(十八)支持不同设备——支持不同的屏幕

Android 丨 获取屏幕尺寸与密度

Android应用程序支持不同屏幕(尺寸密度)

Android 屏幕适配基础

Android官方开发文档Training系列课程中文版:多样屏幕之支持不同的屏幕密度