Android如何处理多个屏幕...(相对布局或线性布局)?

13

我已经完成了我的应用程序,现在需要适配多个屏幕尺寸。

目前看来,我唯一的选择是执行以下操作:

  • 为小屏幕、普通屏幕、大屏幕和超大屏幕分别准备一个xml布局。
  • 在此之内,为ldpi、mdpi、hdpi和xhdpi分别准备一个xml布局。
  • 在此之内,为竖屏和横屏各准备一个xml布局。

这总共需要为一个活动创建32个布局。

我只是想知道是否有更好的方法做到这一点,因为这将非常耗时,但是如果需要支持所有可能的设备,我不介意这样做。

我阅读了一些资料,人们建议使用LinearLayout,并使用gravity作为百分比,这样它在所有屏幕上看起来都相同。或者我可以使用RelativeLayout并使用“AlignAbove或Below”等属性。

然而,我的主要问题是尺寸不正确,尽管元素的位置似乎基本正确。

有没有广泛接受的方法来处理这个问题?

我真的只是想知道普通开发者处理所有屏幕尺寸的“主流”方法。


它为什么不支持具有不同密度的设备?您能描述一下吗? - Saeed Entezari
1
@ranjith,你对我发布的答案有什么问题吗?我还能以其他方式帮助你吗? - Aritra Roy
4个回答

15

好问题。但是你目前的做法不是一个"专业"开发者所应该做的。 你不需要为单个Activity创建32个布局,Android足够智能来处理这些事情。

没有多重定义布局/ dimens.xml,是否支持多设备?

是的,这是完全可行的,也是你应该做的。为单个Activity布局定义32个布局不是一件好事。

假设我在Play Store上有一个相当大的应用程序,拥有20多个活动,如果我为单个Activity定义了32个布局,那么我的应用程序将会有超过600个布局。 这可行吗?自问一下吧。

你首先需要开始阅读这个页面。它包含了几乎你需要知道的所有内容。但我会帮助你正确地进行。

您不需要为每种屏幕大小和密度的每个组合提供替代资源。系统提供了强大的兼容性功能,可以处理大部分呈现您的应用程序的工作,只要您使用允许它优雅调整大小的技术来实现您的UI

这个声明足以使你相信你不应该这样做。Android系统足够智能,可以相应地调整你的布局大小。相信我,在这方面它真的很好。

当您为不同的屏幕尺寸设计UI时,您会发现每种设计都需要一定量的空间。因此,上面的每个广义屏幕尺寸都有一个与之关联的最小分辨率,由系统定义。这些最小尺寸以“dp”单位表示-定义布局时应使用相同的单位

我将指出一些你需要考虑的重要事项。

  • 永远不要在布局中硬编码像素。
  • 始终在布局中使用dpsp。顾名思义,它们与不同设备的密度无关,因此在每个设备上看起来都是一样的。
  • 始终对高度和宽度使用wrap_contentmatch_parent
  • 永远不要使用AbsoluteLayout
  • RelativeLayoutLinearLayout都适用于您,您只需要根据场景决定要使用哪一个
  • 始终为不同屏幕大小提供不同版本的可绘制资源。这是您不能跳过的事情。如果不这样做,不仅会使您的布局在不同设备上看起来很糟糕,而且还会使您的应用程序消耗不必要的资源。
  • 虽然单个布局也适用于平板电脑,但由于平板电脑的屏幕尺寸比典型手机大得多,您应该为它们提供单独的布局。
  • Android Studio 丰富的布局编辑器

    Android Studio拥有一个惊人的布局编辑器,您可以即时预览您的布局。只需看下面的截图,

    enter image description here

    我在所有屏幕尺寸中同时预览我的应用程序的特定屏幕,我的布局在所有屏幕上看起来都像我想要的一样。

    对于此Activity,我只有两个布局,一个适用于所有手机,另一个适用于所有平板电脑。

    实践经验

    如果您想要实践经验,我在Play商店上有一个应用程序,它在8000多种不同屏幕大小的超过8000台设备上由数千名用户使用。

    我只有两个用于特定 Activity 的布局,一个用于手机,一个用于平板电脑。我的应用程序的用户界面在所有设备上看起来都很好,从来没有任何用户对此提出过抱怨。如果需要的话,这里 是该应用程序的链接。

    我相信这个详细的答案可以澄清你所有的疑惑,如果不行,请不要犹豫让我知道。我很乐意帮助您进一步。

    更新

    我将再次尝试澄清您的困惑。但首先,我建议您多读几遍我的答案

    无论您需要一个还是两个布局,这完全取决于您正在设计的特定布局。所有布局都与其他布局不同。 它无法被技术上定义,因为这是主观的。 没有固定规则。但我会尝试以正式的方式帮助您。

    您需要充分利用Android Studio丰富的布局编辑器及其令人惊叹的实时预览功能。

    • 首先,尝试设计针对任何平均设备大小(例如Nexus 5的5英寸)的布局。只需选择Nexus 5以预览您的布局。

    • 一旦您对设计满意,请选择其他屏幕大小以预览它们。您还可以选择“预览所有大小”,如上图所示。

    • 尝试查看您的布局是否在所有屏幕大小上都好看,从4英寸到10英寸的平板电脑不等。请查看间距、图像大小和字体大小是否都正确。

    • 所有的手机屏幕从4英寸到6英寸都通常会有完美的预览,但是您可能需要单独为平板电脑屏幕设计另一个布局(因为它们足够大)。只有这里才需要两个布局,但并不总是需要。

    就像在我的应用程序中,只有5-6个活动需要2个单独的布局,但对于其他的,我只有一个布局。这完全取决于特定的布局。

    设计与编程完全不同。编程可以被正式和语法化地定义,但设计无法被定义。设计是绝对主观的,并且取决于设计师的视角。以自己的方式创造性地设计,那就是设计的魔力


@KingofMasses 谢谢! - Aritra Roy
1
@ranjith 我已经更新了答案。我尽力消除了你的困惑。如果你还有任何疑问,请不要犹豫让我知道。 - Aritra Roy
1
我使用4个dimens.xml值(small,normal,large,xlarge).. 这种方法正确吗? - Ranjithkumar
1
是的,没错。使用4 dimens.xml没有问题。但请务必使用实时预览来检查布局,确保正确的尺寸被应用。 - Aritra Roy
1
@ranjith 谢谢。很高兴能帮忙。 - Aritra Roy
显示剩余4条评论

3

然而,我的主要问题是尺寸不正确,虽然元素的位置似乎大体上是正确的。

您是否正确使用了dp和sp单位?

dp

密度无关像素 - 这是一个基于屏幕物理密度的抽象单位。这些单位与160dpi(每英寸点数)的屏幕相关,在该屏幕上,1dp大约等于1px。当运行在更高密度的屏幕上时,用于绘制1dp的像素数量会按适合屏幕dpi的因子进行缩放。同样地,当在较低密度屏幕上时,用于1dp的像素数量会缩小。dp到像素的比率将随着屏幕密度而改变,但不一定成正比例。使用dp单位(而不是px单位)是使布局中视图尺寸能够针对不同屏幕密度正确调整大小的简单解决方案。换句话说,它提供了UI元素在不同设备上的真实尺寸的一致性。

sp

可缩放独立像素 - 这类似于dp单位,但也根据用户的字体大小偏好进行缩放。建议您在指定字体大小时使用此单位,以便将其调整为屏幕密度和用户偏好两者都适用的大小。

来自Android文档


所有我的单位都是以 dp 为单位,然而在不同的密度下,一个 dp 的值是不同的。因此,在高密度手机上,一个 dp 的值只有低密度手机上的一半。所以,在低密度手机上,所有的边距都应该是它们应该是的一半。在这种情况下,dp 没有帮助。 - droider
显然,制作32种不同的布局并不是正确的选择。在我看来,使用LinearLayout来使用百分比值是一个不错的选择。你正在使用哪种视图?也许改变缩放属性可以帮助解决问题。 - oxygenpt
我的应用程序的主要活动是一个ImageView。根据持续的研究,我发现一种方法是为每个屏幕大小做一个layoutland/port,并根据ldpi、mdpi、hdpi和xhdpi提供不同的图像。我将进行一些测试,看看这是否提供了所需的结果。 - droider
1
请查看此线程,它可能会对您有所帮助:https://dev59.com/QHE85IYBdhLWcg3w9orw - oxygenpt

1
我认为阅读文档很有好处,它们详细解释了支持多屏幕的每一个方面。但是大家都会困惑如何何时使用它,我说得对吗?在困惑之前,可以下载官方示例代码iosched,试着理解一下他们如何管理支持屏幕的内容。第一次理解那段代码可能很难,但我们是开发人员,所以...例如:我有一台安卓设备,支持API 10-22和所有从Galaxy star s5280(非常小的屏幕)到10英寸平板电脑Nexus 10的所有设备。如何管理资源?

POINT-1 从布局开始

创建两个布局如下所示

res/layout/my_layout.xml   
res/layout-sw600dp/my_layout.xml // 7 inch tablets

以下是可选项,仅在需要非常小或大的布局时使用。
res/layout-small/my_layout.xml
res/layout-sw720dp/my_layout.xml // 10 inch tablets

POINT-2 您也可以使用尺寸来管理布局

res/values/dimens.xml
res/values-sw600dp/dimens.xml // 7 inch tablets
res/values-sw720dp/dimens.xml // 10 inch tablets

POINT-3 添加不同的可绘制对象

res/drawable-mdpi/graphic.png 
res/drawable-hdpi/graphic.png 
res/drawable-xhdpi/graphic.png 
res/drawable-xxhdpi/graphic.png 

根据我的经验,每个人都使用POINT 1和2的组合(根据需求),而POINT-3是普适的:)。阅读最佳实践


最后别忘了在Android清单文件中使用<supports-screens><compatible-screens>标签。


编辑:

我能使用values-large和values-xlarge吗?我对values-large和values-sw600dp感到困惑

注意:从Android 3.2(API级别13)开始,这些大小组已被弃用,改为基于可用屏幕宽度管理屏幕大小的新技术。如果您正在开发适用于Android 3.2及更高版本的应用程序,请参阅声明Android 3.2平板电脑布局以获取更多信息。

首先阅读上述指南,根据指南,我们不必使用例如large或xlarge,只需使用宽度为600dp。这适用于>= 3.2 Android操作系统。在每个设备上都可以正常工作,但您可能会在GALAXY系列设备(如GALAXY TAB-2,GRAND)中遇到问题,因为它们具有旧的API,此时可以使用values-large和values-xlarge。这是设备特定的问题,仅在必要时才执行。


还有一点需要注意,就是按照需要创建多个文件来创建上述布局,例如我们在布局中有一个listview,那么只需创建一个文件,其在所有设备(包括平板电脑)上都相同。 通过这种方式,您还可以管理应用程序的大小。

线性布局、相对布局和框架布局能够让您的生活更加轻松。


我可以使用values-large和values-xlarge吗?我对values-large和values-sw600dp感到困惑。 - Ranjithkumar
@ranjith:请检查我在答案中的编辑,如果有其他问题,请评论。 - Dhaval Parmar
谢谢你再次给出的好答案。但是我不能投两次票了,我已经把赏金给了另一个人。祝你有愉快的一天。 - Ranjithkumar

0
你可以通过动态设计布局来实现这一点。它适用于所有屏幕。在Android中,我们无法得出可用移动屏幕的结论。有许多具有不同分辨率的屏幕。为了使UI具有灵活性,您需要动态设计布局。 例如,我添加了一个XML文件,可以适用于所有屏幕(纵向)。
XML如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10"
android:gravity="center">


<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="0dip"
    android:layout_weight="4"
    android:weightSum="10"
    android:gravity="center">

    <ImageView
         android:layout_width="0dip"
        android:layout_weight="3"
        android:layout_height="match_parent"
        android:src="@mipmap/ic_launcher"
        android:id="@+id/imageView3" />
</LinearLayout>

</LinearLayout>

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