适配所有设备的Android启动画面图片尺寸

227

我有一个全屏的PNG图片,想要在启动画面上显示。但是我不知道应该在每个drawable文件夹(ldpi, mdpi, hdpi, 和 xhdpi)里放置什么尺寸的图片。我的应用程序应该在所有手机和平板电脑上都能展示得很好,很漂亮。为了让启动画面在所有屏幕上都显示得漂亮,应该创建哪些尺寸(以像素为单位)的图片呢?


6
好的,以下是您所请求的翻译内容:标题:使用 SlidingPaneLayout 打造真正的 Master/Detail 流程在 Android 应用程序中,Master-Detail 流程通常用于显示层次结构数据。这种模式包括两个连续的面板:一个面板列出了所有可用的数据项(即“Master”),另一个面板则显示所选数据项的详细信息(即“Detail”)。在较小的设备上,这两个面板通常分别占用整个屏幕。但是,在大屏幕上,如平板电脑或桌面计算机,这种布局会显得过于简单并浪费了空间。因此,许多应用程序都采用了一种更灵活的方式来管理这种布局:将两个面板并排放置,并通过向左滑动 “Master” 来显示 “Detail”。在本文中,我将介绍一种名为 SlidingPaneLayout 的 Android 布局,它使得实现这种 Master-Detail 模式更加容易。我将向您展示如何使用它来构建一个真正的 Master-Detail 流程。SlidingPaneLayout 的基础知识SlidingPaneLayout 是一个可以将两个子视图组合在一起的 Android 布局。默认情况下,第一个子视图覆盖了第二个子视图。但是,通过向右侧滑动第一个子视图,可以暴露出第二个子视图。以下是创建 SlidingPaneLayout 的 XML 布局的示例: 在这个布局中,我们定义了两个子视图:Master 和 Detail。Master 视图使用固定宽度(在本例中为 240dp),而 Detail 视图则填充整个剩余空间。要在代码中使用 SlidingPaneLayout,您需要获取对两个子视图的引用,然后根据需要调整它们的大小和位置。以下是一个获取 Master 视图引用并将其大小设置为屏幕宽度 1/2 的示例:SlidingPaneLayout slidingPaneLayout = findViewById(R.id.sliding_pane_layout); View masterView = findViewById(R.id.master_pane); DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); int screenWidth = displayMetrics.widthPixels; masterView.getLayoutParams().width = screenWidth / 2;这就是如何创建和配置 SlidingPaneLayout 的基础知识。接下来,我将向您展示如何在真实应用程序中使用它来实现 Master-Detail 流程。使用 SlidingPaneLayout 实现 Master-Detail 流程为了演示如何在 Android 应用程序中使用 SlidingPaneLayout 来实现 Master-Detail 流程,我们将构建一个名为 CheeseDetail 的简单应用程序。这个应用程序显示了一些奶酪名称,并在用户点击某个奶酪时显示有关该奶酪的详细信息。以下是应用程序的主活动的 XML 布局: - CommonsWare
4
我想创建一个启动画面... - arielschon12
1
@verybadalloc 可能更深入,但我可以向您保证,它对OP的问题没有帮助,因为它发布得太晚了一年:p - keyser
6
是的,我相当确定这没有帮助他。在试图找到答案时,我发现了这个话题,并决定发布另一个答案来帮助在我之后经历同样问题的人们。 - Lucas Cerro
我回答过类似的问题,可能会有帮助。http://stackoverflow.com/questions/30494811/android-splash-screen-dimensions/36381610#36381610 - Ramesh K
https://dev59.com/91kT5IYBdhLWcg3wB7Es#39173958 - ℛɑƒæĿᴿᴹᴿ
11个回答

407

免责声明

本回答发布于2013年,内容已过时。从Android 3.2开始,现在有6个屏幕密度组。 我会尽快更新此答案,但无法确定时间。 如果需要了解目前所有密度的信息(尽管特定像素大小的信息永远很难找到),请参阅官方文档

以下是简略版:

  • 为每种屏幕密度创建4种图像:

    • xlarge(xhdpi):640x960
    • large(hdpi):480x800
    • medium(mdpi):320x480
    • small(ldpi):240x320
  • 在Android开发者指南中阅读9-patch图像介绍

  • 设计具有可以安全拉伸的区域的图像,而不会影响最终结果

有了这些,Android将为设备的图像密度选择适当的文件,然后根据9-patch标准拉伸图像。

简略版结束,以下是完整内容

我回答与问题相关的设计方面。 我不是开发人员,因此无法提供实现许多解决方案所需的代码。 然而,我的意图是帮助像我一样迷失的设计师们,在开发他们的第一个Android应用时做出正确选择。

适配各种尺寸

使用Android,公司可以开发几乎任何大小、几乎任何分辨率的手机和平板电脑。 因此,闪屏界面没有固定的屏幕分辨率,也就不存在“正确的图像大小”。这对于想要实现闪屏界面的人来说是个问题。

您的用户真的想看到闪屏界面吗?

(顺便说一句,可用性专家们并不赞成使用闪屏界面。 有人认为,用户已经知道自己点击了哪个应用程序,使用闪屏界面来品牌化图片并不必要,因为它只会通过“广告”打断用户体验。 但是,它应该在初始化时需要较长时间加载(5秒以上)的应用程序中使用,包括游戏等,以使用户不会卡住想知道应用程序是否已崩溃)

屏幕密度;4个类别

因此,鉴于市场上不同的手机屏幕分辨率如此之多,Google实施了一些替代方案和巧妙的解决方案,可以提供帮助。 您必须知道的第一件事是,Android将所有屏幕分为4个不同的屏幕密度类别:

  1. 低密度 (ldpi ~ 120dpi)
  2. 中等密度 (mdpi ~ 160dpi)
  3. 高密度 (hdpi ~ 240dpi)
  4. 超高密度 (xhdpi ~ 320dpi) (这些dpi值是近似值,因为定制设备将具有不同的dpi值)

如果你是设计师,你需要知道的是Android基本上会从4个图像中选择要显示的图像,具体取决于设备。因此,你基本上需要设计4个不同的图像(尽管可以为不同的格式(如宽屏、纵向/横向模式等)开发更多的图像)。

记住,除非你为Android中使用的每个分辨率都设计一个屏幕,否则你的图像将被拉伸以适应屏幕大小。除非你的图像基本上是渐变或模糊,否则在拉伸时会出现一些不良扭曲效果。因此,你基本上有两个选项:为每个屏幕大小/密度组合创建一个图像,或创建四个9-patch图像。

最困难的解决方案是针对每个分辨率设计不同的启动屏幕。你可以先按照此页面末尾的表格中的分辨率进行设计(还有更多。例如:960 x 720没有列出)。并且假设你在图像中有一些小细节,比如小字体,你必须为每个分辨率设计多个屏幕。例如,在中等屏幕上显示的480x800图像可能看起来还可以,但在更小的屏幕上(具有更高密度/dpi),标志可能会变得太小,或者某些文本可能变得无法阅读。

9-patch图像

另一种解决方案是创建9-patch图像。它基本上是一个围绕着你的图像的1像素透明边框,通过在这个边框的顶部和左侧区域画黑色像素,你可以定义哪些部分允许拉伸你的图像。我不会详细介绍9-patch图像的工作原理,但简而言之,与顶部和左侧区域的标记对齐的像素是将被重复以拉伸图像的像素。

一些基本规则

  1. 你可以使用Photoshop (或任何可以准确创建透明png的图像编辑软件)来制作这些图片。
  2. 1像素的边框必须完全透明。
  3. 1像素的透明边框必须围绕在您的图像周围,而不仅仅是顶部和左侧。
  4. 在这个区域内,你只能使用黑色(#000000)像素。
  5. 顶部和左侧边框(用于定义图像拉伸)只能有一个点(1px x 1px),两个点(都是1px x 1px)或者一个连续的线(宽度x1px或1px x高度)。
  6. 如果选择使用2个点,则图像将按比例扩展(因此每个点将轮流扩展,直至达到最终宽度/高度)。
  7. 1像素边框必须加在原始尺寸之外。因此,一个100x100的9-patch图像实际上必须有102x102(100x100 + 1像素的顶部、底部、左侧和右侧)。
  8. 9-patch图像的文件名必须以*.9.png结尾。

所以,在您的标志的任一侧(在上边框上)可以放置1个点,在其上下各放置1个点(在左边框上),这些标记的行和列将是唯一会被拉伸的像素。

示例

这是一个9-patch图像,大小为102x102像素(最终的app尺寸为100x100):

9-patch image, 102x102px

这是相同图像的200%缩放版本:

the same image, magnified 2x for clarity

请注意,顶部和左侧的1px标记指示哪些行/列将被扩展。

这是在app内渲染成100x100的样子:

rendered into 100x100

这是将其扩展到460x140的样子:

rendered into 460x140

还有一件事需要考虑。这些图片在您的显示器和大多数手机屏幕上看起来很好,但是如果设备具有非常高的图像密度(dpi),那么该图像将会显得太小。可能仍然可读,但在分辨率为1920x1200的平板电脑上,该图像将显示为中间的一个非常小的正方形。那么有什么解决办法呢?为每个密度集设计4个不同的9-patch启动器图像。为了确保不会发生缩小,应为每个密度类别设计最低公共分辨率。这里不希望发生缩小,因为9-patch仅考虑拉伸,在缩小过程中,小文字和其他元素可能会失去清晰度。
以下是每个密度类别最小、最常见的分辨率列表: - xlarge (xhdpi): 640x960 - large (hdpi): 480x800 - medium (mdpi): 320x480 - small (ldpi): 240x320
因此,请使用上述分辨率为四个闪屏设计扩展图片,用1像素的透明边框围绕画布,并标记哪些行/列可以被拉伸。请记住,这些图像将用于密度类别中的任何设备,因此您的ldpi图像(240 x 320)可能会被拉伸到具有小图像密度(~120 dpi)的超大型平板电脑上的1024x600。因此,只要您不想在启动画面中使用照片或复杂的图形(请在设计时牢记这些限制),9-patch就是最好的拉伸解决方案。
再次强调,避免发生拉伸的唯一方法是为每个分辨率设计一个屏幕(或者针对每个分辨率-密度组合设计一个屏幕,如果您希望避免在高/低密度设备上图像变得太小/太大),或者告诉图像不要拉伸,并使背景色出现在拉伸的位置(还要记住,由Android引擎呈现的特定颜色可能与Photoshop呈现的相同特定颜色看起来不同,因为涉及到颜色配置文件)。
希望以上内容能让您理解。

8
在实践中我发现了一个问题。如果你使用9-patch图片,它的大小需要小于你所支持的最小屏幕尺寸。这个图片似乎会被放大,但不会被缩小,导致裁剪...并且好像需要设置为fitXY。 - Sean Aitken
谢谢你的评论,CleverCoder。你能详细说明一下多少尺寸更小是理想的,以避免任何问题吗?我假设宽度和高度缩小2像素就足够了? - Lucas Cerro
1
你说“xlarge(xhdpi):640x960”,但是文档说xlarge至少为960dp x 720dp,因此具有xhdpi密度的xlarge屏幕应该是1920px x 1440px。密度和尺寸是不同的概念。 - fikr4n
1
@LucasCerro:你应该考虑在这个非常好的答案的第一行上进行编辑,说明这个答案已经过时了,并且从Android 3.2开始,现在有6个基于可用屏幕宽度的组。 - Jens
好的,@Jens。我正在完成一个项目,完成后会更新新的见解。 - Lucas Cerro
显示剩余7条评论

130

竖屏模式

MDPI为320x480 dp = 320x480像素 (1x)

LDPI为0.75 x MDPI = 240x360像素

HDPI为1.5 x MDPI = 480x720像素

XHDPI为2 x MDPI = 640x960像素

XXHDPI为3 x MDPI = 960x1440像素

XXXHDPI为4 x MDPI = 1280x1920像素

横屏模式

MDPI为480x320 dp = 480x320像素 (1x)

LDPI为0.75 x MDPI = 360x240像素

HDPI为1.5 x MDPI = 720x480像素

XHDPI为2 x MDPI = 960x640像素

XXHDPI为3 x MDPI = 1440x960像素

XXXHDPI为4 x MDPI = 1920x1280像素

编辑:

如果您在2019年或之后阅读此内容,我建议使用Lottie来制作启动画面。


1
太好了!我正在寻找这个。 - Lion789
最有用的解决方案 - Farzad Yousefzadeh
6
这些数值似乎不正确。XXHDPI 应该是1920x1080。 - user2966445
是的!谢谢,这就是我在寻找的!非常感谢! - theHellyar
请问平板电脑的尺寸如何? - Beeing Jk

30

人像画

LDPI:200x320像素

MDPI:320x480像素

HDPI:480x800像素

XHDPI:720x1280像素

风景画

LDPI:320x200像素

MDPI:480x320像素

HDPI:800x480像素

XHDPI:1280x720像素


2
物理屏幕尺寸和分辨率是独立的概念。像素图像的大小是两者的乘积。 - Henry
1
请告诉我XXHDPI和XXXHDPI的尺寸大小。 - hitesh141
这个答案中的值似乎与此处提供的信息不成比例:https://dev59.com/yGIk5IYBdhLWcg3wBqCW#19661363。我认为虽然较旧,但被接受的答案更有可能是正确的。 - ban-geoengineering

17

12

使用PNG并不是一个好的想法。实际上,就性能而言,它是昂贵的。您可以使用可绘制的XML文件,例如Facebook的背景

这将帮助您提高性能的流畅度和速度,并且对于标志,使用.9图像。


11
Density buckets

LDPI    120dpi    .75x
MDPI    160dpi    1x
HDPI    240dpi    1.5x
XHDPI   320dpi    2x
XXHDPI  480dpi    3x
XXXHDPI 640dpi    4x

px / dp = dpi / 160 dpi

6
在我的情况下,我在style.xml中使用了列表drawable。使用图层列表drawable,您只需要一个png文件即可适用于所有屏幕尺寸。
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">@drawable/flash_screen</item>
    <item name="android:windowTranslucentStatus" tools:ignore="NewApi">true</item>
</style>

在drawable文件夹中有一个flash_screen.xml文件。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"></item>
    <item>
        <bitmap android:src="@drawable/background_noizi" android:gravity="center"></bitmap>
    </item>
</layer-list>

"background_noizi"是drawable文件夹中的PNG文件。希望这有所帮助。

3
如果您的背景图片过大,它将会被拉伸。 - ShadeToD

5

4

编辑后的解决方案将使您的启动屏在所有API上看起来更加出色,包括API21到API23

如果您只针对API24+进行定位,则可以直接在其xml文件中缩小矢量可绘制对象,如下所示:

<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="640"
android:viewportHeight="640"
android:width="240dp"
android:height="240dp">
<path
    android:pathData="M320.96 55.9L477.14 345L161.67 345L320.96 55.9Z"
    android:strokeColor="#292929"
    android:strokeWidth="24" />
</vector>

在上面的代码中,我正在重新调整我在640x640画布上绘制的可绘制对象,使其变为240x240。然后我将它放入我的闪屏可绘制对象中,就可以很好地工作了。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"
android:paddingBottom="20dp" android:paddingRight="20dp" android:paddingLeft="20dp" android:paddingTop="20dp">

<!-- The background color, preferably the same as your normal theme -->
<item>
    <shape>
        <size android:height="120dp" android:width="120dp"/>
        <solid android:color="@android:color/white"/>
    </shape>
</item>

<!-- Your product logo - 144dp color version of your app icon -->
<item
    android:drawable="@drawable/logo_vect"
    android:gravity="center">

</item>
</layer-list>

我的代码实际上只绘制了底部图片中的三角形,但您可以看到通过这种方式可以实现什么。与使用位图时出现的像素化边缘相比,分辨率终于很好。因此,请务必使用矢量可绘制(有一个名为Vectr的网站,我用它创建了自己的矢量图,无需下载专门的软件)。

编辑以便在API21-22-23上也能正常工作

虽然上面的解决方案适用于运行API24+的设备,但在安装我的应用程序的API22设备上,我感到非常失望。我注意到启动画面再次尝试填充整个视图并且看起来很糟糕。在拔掉半天眉毛之后,我最终通过纯意志力 brute-forced 找到了解决方案。

你需要创建一个名为splash_screen.xml的第二个文件,并将其放置在res/文件夹中创建的drawable-v22和drawable-v21两个文件夹中(要查看它们,您需要将项目视图从Android更改为Project)。这样可以告诉您的手机,在相关设备运行与drawable文件夹中的-vXX后缀对应的API时,重定向到放置在这些文件夹中的文件,请参阅此链接。将以下代码放置在您在这些文件夹中创建的splash_screen.xml文件的Layer-list中:

<item>
<shape>
    <size android:height="120dp" android:width="120dp"/>
    <solid android:color="@android:color/white"/>
</shape>
</item>

<!-- Your product logo - 144dp color version of your app icon -->
<item android:gravity="center">
    <bitmap android:gravity="center"
        android:src="logo_vect"/>

</item>

these is how the folders look

由于某些API的原因,您必须将可绘制对象包装在位图中才能使其正常工作,而最终结果看起来相同。问题在于,您必须使用附加的可绘制文件夹作为splash_screen.xml文件的第二个版本,否则,对于运行API高于23的设备,您的启动屏幕将不会显示。您还可能需要将splash_screen.xml的第一个版本放入drawable-v24中,因为Android默认使用它可以找到的最接近的drawable-vXX文件夹作为资源。希望这有所帮助。

my splashscreen


3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接