如何设置Android布局以支持所有屏幕尺寸?

30

我正在开发一个在Android版本2.2上的程序。我已经阅读了许多关于支持多个屏幕尺寸的文档,但仍感到困惑。我设计了一个布局文件,支持大屏幕和普通屏幕,但当我尝试在小屏幕上运行它时,它没有调整布局以适应屏幕。我也在清单文件中使用了这段代码。

<supports-screens 
        android:resizeable="true"
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:anyDensity="true"
        />

小屏幕的图像在这里。如何设置适用于小屏幕的屏幕?我在某处发现可以通过使用文件夹“layout-small”来实现,但是如果我使用这个文件夹,项目大小会增加,我不想这样,所以有人能建议我最好的方法吗?


请参考这个链接,我认为它会帮助解决你的问题:http://stackoverflow.com/questions/16495283/google-play-console-unsupported-devices-808 - Siddharth
请查看我在此处的答案:http://stackoverflow.com/questions/36820746/how-to-design-any-screen-size-and-density-in-androidmulti-screen-for-mobiles/36821546#36821546 - mehrdad khosravi
8个回答

39

适用于所有屏幕并支持所有布局的解决方案。

图标:

                                 mdpi        hdpi       xhdpi       xxhdpi       xxxhdpi  
Launcher Icons (App Icons)      48 x 48     72 x 72    96 x 96     144 x 144    192 x 192
Action Bar,Toolbar,Tab Icons    24 x 24     36 x 36    48 x 48      72 x 72      96 x 96 
Notification Icons              24 x 24     36 x 36    48 x 48      72 x 72      96 x 96 

背景图片分辨率:

ldpi:    Portrait: 240 X 320px.      Landscape: 320 X 240px.
mdpi:    Portrait: 320 X 480px.      Landscape: 480 X 320px.
hdpi:    Portrait: 480 X 800px.      Landscape: 800 X 480px.
xhdpi:   Portrait: 640 X 960px.      Landscape: 960 X 640px.
xxhdpi:  Portrait: 960 X 1600px.     Landscape: 1600 X 960px.
xxxhdpi: Portrait: 1280 X 1920px.    Landscape: 1920 X 1280px.  

可绘制文件夹:

res/drawable        (default)
res/drawable-ldpi/  (240x320 and nearer resolution)
res/drawable-mdpi/  (320x480 and nearer resolution)
res/drawable-hdpi/  (480x800, 540x960 and nearer resolution)
res/drawable-xhdpi/  (720x1280 - Samsung S3, Micromax Canvas HD etc)
res/drawable-xxhdpi/ (1080x1920 - Samsung S4, HTC one, Nexus 5, etc)
res/drawable-xxxhdpi/ (1440X2560 - Nexus 6,Samsung S6edge).


ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi

布局:

Portrait: 
res/layout/main_activity.xml           # For handsets (smaller than 600dp available width)
res/layout-large/main_activity.xml     # For small tablets (640dp x 480dp and bigger)
res/layout-xlarge/main_activity.xml    # For large tablets (960dp x 720dp and bigger)
res/layout-w600dp/main_activity.xml    # For 7” tablets or any screen with 600dp
                                       # available width (possibly landscape handsets)

Landscape:
res/layout-land/main_activity.xml           # For handsets in landscape
res/layout-sw600dp-land/main_activity.xml   # For 7” tablets in landscape

参考链接:

Android不同分辨率支持

https://developer.android.com/guide/practices/screens_support.html

https://design.google.com/devices/

所有基于Android的手机和平板电脑的屏幕分辨率列表在哪里?

http://www.emirweb.com/ScreenDeviceStatistics.php

Android手机上最受欢迎的屏幕尺寸/分辨率


22

1
谢谢,它运行得很好,但我想知道是否有更好的方法来支持屏幕尺寸而不需要分叉文件夹? - wolverine
不客气。据我所知,没有任何解决办法。这可能是唯一的方法。如果还有其他方法,那么该方法就会被纳入到Android开发者网站中。 - Ghost
1
那个解决方案完美地运作了。但我在这里的担忧是,当我有一个包含8-9个屏幕的Android应用程序时,这意味着我将拥有8-9个不同的.xml布局文件。现在为了通过文件夹分流支持所有屏幕,这意味着我必须管理几乎超过50个xml文件的布局,并且对于UI的简单更改,必须进入所有文件夹并在xml文件中实现该更改。那么是否有更好的方法,我的意思是这样一种布局,可以自动调整控件大小或类似的东西? - Muhammad Salman Farooq
@MuhammadSalmanFarooq:实际上,我在两年前就退出了Android开发。所以,我现在只能猜测。我建议您在网上搜索或在SO上提出另一个问题,以回答您的这个问题。 - Ghost
什么是分叉 - IgorGanapolsky

12

是的,我已经找到了解决方案,我个人认为为每个屏幕分辨率制作布局很耗时间,会使项目变得更大。

为了创建适合所有屏幕分辨率的布局,我采用了自己的技巧,即按百分比设置宽度和高度。

当我们使用某些常量宽度或高度值(例如100dp)来设置视图/布局时,就会出现问题。

解决方案很简单,尝试使用match_parent,这样视图将填充空白空间,或者使用weight并相对于其他视图定义每个视图。这将帮助您的布局在几乎所有屏幕分辨率下都看起来很好,并在运行时设置只有那些以百分比为单位具有某些常量宽度或高度的视图/布局的LayoutParams。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/mLayout"
        android:layout_width="280px"
        android:layout_height="300px" />


</RelativeLayout>

注意:在固定尺寸布局的宽度/高度中,我使用了px,因为在LayoutParams layoutParams = new LayoutParams(int width, int height);中,widthheight取值为像素

这是一个示例代码

final ViewTreeObserver mLayoutObserver = mLayout.getViewTreeObserver();

    mLayoutObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
    {

        @Override
        public void onGlobalLayout() 
        {
            DisplayMetrics metrics = getResources().getDisplayMetrics();

            int deviceWidth = metrics.widthPixels;

            int deviceHeight = metrics.heightPixels;

            float widthInPercentage =  ( (float) 280 / 320 )  * 100; // 280 is the width of my LinearLayout and 320 is device screen width as i know my current device resolution are 320 x 480 so i'm calculating how much space (in percentage my layout is covering so that it should cover same area (in percentage) on any other device having different resolution

            float heightInPercentage =  ( (float) 300 / 480 ) * 100; // same procedure 300 is the height of the LinearLayout and i'm converting it into percentage

            int mLayoutWidth = (int) ( (widthInPercentage * deviceWidth) / 100 );

            int mLayoutHeight = (int) ( (heightInPercentage * deviceHeight) / 100 );

            LayoutParams layoutParams = new LayoutParams(mLayoutWidth, mLayoutHeight);

            mLayout.setLayoutParams(layoutParams);
        }
    });

如果有人仍需要帮助,我想代码已经很容易理解了,您可以立即提出问题。

结论:如果您需要为您的Views/Layouts设置一些常量宽度/高度,请在布局文件(即xml)中以px为单位设置值,然后编程方式设置LayoutParams

建议:我认为Google Android Guys应该认真考虑将dp/dip单位替换为百分比


Muhammad Babar,你说的部分正确。但是对于那些无法应用九宫格并统一拉伸的图标,你需要为不同的屏幕定义布局以使用不同的图片。 - Raj
请问你能否帮我参考一下这个问题?我尝试引用这些文件夹中的图像,并为同一个XML文件创建不同的布局,但是这些图像并没有根据屏幕分辨率显示。http://stackoverflow.com/questions/17590254/targeting-multiple-screen-sizes-in-android-how-to?noredirect=1#comment25598107_17590254 - Raj
@MuhammadBabar 请帮帮我!当我尝试将您的方法添加到我的XML中时,出现了错误。"当前的Android SDK版本不支持RelativeLayout作为XML标记。我正在使用Flash CS6和Flash Develop AS3来创建这个Android AIR应用程序。我的SDK版本是4.0。它是最新的SDK。 - Nathan
@user2233653,老实说我对Flash和AIR没有任何经验。RelativeLayout只是一个例子,你可以将LinearLayout作为父级 - Muhammad Babar
2
我创建了一个新的尺寸单位,它实际上是你想要的百分比,你可以在 github 上找到它。 - Elhanan Mishraky
显示剩余2条评论

8
现在支持不同屏幕尺寸更加容易了!使用新的尺寸单位SDPSDP - 一种可缩放的尺寸单位。
一个 Android SDK 提供了一种新的尺寸单位 - sdp(可缩放 dp)。这个尺寸单位会随着屏幕尺寸进行缩放。它可以帮助 Android 开发者支持多个屏幕。
对于文本视图,请参考基于 sp 尺寸单位的 ssphttps://github.com/intuit/sdp

2
我遇到的最好的解决方案之一。只需将“implementation 'com.intuit.sdp:sdp-android:1.0.6'”添加到您的依赖项中,您就可以立即开始使用了。对这个答案点赞。 - Arjun
我似乎找不到文本的“ssp”单元,只有“ssp”。现在无所谓,但是这两个单元需要不同的库吗? - Kleysley
我尝试添加库,但当我将该维度添加到我的布局中时,会出现找不到资源的错误消息。 - Joseph Ofem

1
Scalable DP (sdp) 是最好的解决方案。它会根据屏幕大小调整小部件的大小。我们还可以将其应用于不同文本大小。
要将 sdp 添加到您的项目中(使用 Android Studio 和 Gradle):
将 implementation 'com.intuit.sdp:sdp-android:1.0.5' 添加到您的 build.gradle 依赖项块中。
for example:
dependencies {'com.intuit.sdp:sdp-android:1.0.5' }

有其他人使用过它并对此有反馈吗?我正在使用它,似乎非常容易使用,唯一的问题是您无法完全控制大小... - DragonFire

0
请尝试这个:

尝试这个

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintDimensionRatio="1:1"
    android:scaleType="fitXY"
    android:adjustViewBounds="true"
    android:src="@drawable/myimage"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintStart_toStartOf="parent"/>


0

试试这个库,它很棒

implementation 'com.intuit.ssp:ssp-android:1.0.6'

例子

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Sign up"
        android:textSize="@dimen/_16ssp" />

-1

我不确定这个解决方案是否适用于所有情况,但我想与您分享,它可以覆盖大部分区域。

我通过使用LinearLayout对屏幕进行分区并定义其方向(水平或垂直),layout_weightsum = 3(3是将屏幕分成3部分)来解决了这个问题。

然后,在根线性布局中,我再次采用LinearLayout,其中layout_height = "0dp"(如果您只想要垂直分区,否则layout_height = "wrap_content",如果您需要水平分区,则使layout_width = "0dp"layout_weight =1(1表示屏幕的1部分,您还可以将值放在浮点数中,如1.2)。

您可以尝试一下,它帮助了我,也许会帮助您。


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