如何为Android中的每个不同屏幕尺寸定义dimens.xml?

163

在支持不同屏幕大小(密度)的Android应用中,通常会着重于为每种可能的屏幕创建不同的布局。例如:

  • ldpi
  • mdpi
  • hdpi
  • xhdpi
  • xxhdpi
  • xxxhdpi

我设计了一个用于引用的xhdpi屏幕布局,并在dimens.xml中定义了它的尺寸。现在,我想将其支持到所有可能的屏幕大小。我该如何做?

据我所知,我可以使用这个工具找出其他屏幕尺寸的适当dimens.xml并将其添加到我的项目中。在我的情况下,这是正确的方法吗?

另一个问题,我只需要为以上屏幕尺寸创建dimens.xml吗?如果是,请问w820dp是什么意思?

谢谢你的帮助。我需要支持仅手机(而非平板电脑或其他设备)。


1
是的,您必须为不同的分辨率创建不同的“dimesn.xml”文件。 - Piyush
@PiyushGupta 那对于所有上述维度的屏幕都有效吗?但是W820dp是什么,它是否支持不同的Android版本?另外,您能否为我推荐一些关于基于dimens.xml支持不同屏幕的教程? - Amit Pal
这是为平板电脑或其他设备设计的。否则,如我所说,您需要创建一个不同的值文件夹。 - Piyush
10个回答

317

你需要为不同的屏幕创建不同的值文件夹。 例如

values-sw720dp          10.1” tablet 1280x800 mdpi

values-sw600dp          7.0”  tablet 1024x600 mdpi

values-sw480dp          5.4”  480x854 mdpi 
values-sw480dp          5.1”  480x800 mdpi 

values-xxhdpi           5.5"  1080x1920 xxhdpi
values-xxxhdpi           5.5" 1440x2560 xxxhdpi

values-xhdpi            4.7”   1280x720 xhdpi 
values-xhdpi            4.65”  720x1280 xhdpi 

values-hdpi             4.0” 480x800 hdpi
values-hdpi             3.7” 480x854 hdpi

values-mdpi             3.2” 320x480 mdpi

values-ldpi             3.4” 240x432 ldpi
values-ldpi             3.3” 240x400 ldpi
values-ldpi             2.7” 240x320 ldpi

图片描述

欲了解更多信息,请访问此处

Android中的不同值文件夹

新的工具来管理屏幕尺寸

编辑者@humblerookie

您可以使用名为Dimenify的Android Studio插件,基于自定义比例因子自动生成其他像素桶的尺寸值。它仍处于测试阶段,请务必将您发现的任何问题或建议通知开发者。


1
你的回答中只有"values-sw320dp-hdpi",难道不应该还有"values-sw480dp-xhdpi"、"values-sw480dp-xxhdpi"等吗?请回复。 - Sharp Edge
2
@IntelliJAmiya:你应该提到Android <=3.2和>3.2之间的区别。 - juergen d
5
@IntelliJAmiya,我创建了一个名为Dimenify的工作室插件。它使你能够轻松地为其他桶创建尺寸。你能否添加相同的编辑功能,以便其他人也可以使用它?https://plugins.jetbrains.com/androidstudio/plugin/9349-dimenify - humblerookie
3
这个Dimenify是一个很好的工具。 - Muhammed Refaat
2
如果我们只创建values-sw320dp、values-sw600dp等而不是values-sw320dp-xhdpi、values-sw320dp-hdpi、values-sw320dp-mdpi,是否有很大的区别?那个后缀mdpi/hdpi/xhdpi在values-swXXXdp的末尾是否很重要? - Red M
显示剩余7条评论

57

使用可伸缩DP

虽然针对不同的屏幕尺寸制作不同的布局理论上是个好主意,但要考虑到各种屏幕尺寸和像素密度就会变得非常困难。按照上述答案建议使用20多个不同的dimens.xml文件管理起来也很不容易。

如何使用:

使用sdp

  1. 在你的build.gradle中添加implementation 'com.intuit.sdp:sdp-android:1.0.5'
  2. 将任何dp值,例如50dp,替换为@dimen/50_sdp,如下所示:

    <TextView
     android:layout_width="@dimen/_50sdp"
     android:layout_height="@dimen/_50sdp"
     android:text="Hello World!" />
    

工作原理:

sdp的缩放大小与屏幕尺寸成比例,因为它本质上是不同dp值的大量dimens.xml列表。

enter image description here

在实际操作中查看:

以下是它在三个具有明显不同屏幕尺寸和密度的设备上的效果:

enter image description here

请注意,sdp大小单位计算包括一些近似值,这是由于某些性能和可用性限制所致。


4
非常感谢。这对我来说真的很有用。 - twenk11k
@Advait,你能告诉我在 Samsung Edge 7 上分辨率为 2560x1440 的 5.5 英寸手机中应该使用哪个 values 文件夹吗? - ULHAS PATIL
@Advait S 的意思是为了5.5英寸1080x1920和5.5英寸1440x2560的设备创建不同的文件夹,其中values-xxhdpi适用于前者。 - ULHAS PATIL
不适用于所有设备,当我在平板电脑上打开时大小会改变。 - Arbaz.in
@AndrewGlukhoff 你可以尝试使用负值,最多可达负60个可缩放dp,如下所示:@dimen/_mins60sdp - Advait Saravade
显示剩余3条评论

28

我们想要看到在不同屏幕下所需视图大小的变化。

我们需要为不同的屏幕创建不同的值文件夹,并根据屏幕密度放置dimens.xml文件。

我取了一个TextView,观察了在不同的values文件夹中更改dimens.xml时的变化。

请按照以下步骤进行操作:

normal-xhdpi \ dimens.xml

当我们更改 normal-xhdpi \ dimens.xml 时,以下设备可以更改屏幕大小:

nexus 5X (5.2" * 1080 * 1920 : 420dpi)

nexus 6P (5.7" * 1440 * 2560 : 560dpi)

nexus 6 (6.0" * 1440 * 2560 : 560dpi)

nexus 5 (5.0", 1080 1920 : xxhdpi)

nexus 4 (4.7", 768 * 1280 : xhdpi)

Galaxy nexus (4.7", 720 * 1280 : xhdpi)

4.65" 720p (720 * 1280 : xhdpi)

4.7" WXGA (1280 * 720 : Xhdpi)

Xlarge-xhdpi \ dimens.xml

当我们更改 Xlarge-xhdpi \ dimens.xml 时,以下设备可以更改屏幕大小:

nexus 9 (8.9", 2048 * 1556 : xhdpi)

nexus 10 (10.1", 2560 * 1600 : xhdpi)

large-xhdpi \ dimens.xml

当我们更改 large-xhdpi \ dimens.xml 时,以下设备可以更改屏幕大小:

nexus 7 (7.0", 1200 * 1920: xhdpi)

nexus 7(2012)(7.0英寸,800 * 1280:tvdpi)

以下屏幕在“搜索通用手机和平板电脑”中可见

large - mdpi \ dimens.xml

以下设备可以根据更改 large - mdpi\ dimens.xml 文件来更改屏幕大小

5.1 英寸 WVGA(480 * 800:mdpi)

5.4 英寸 FWVGA(480 * 854:mdpi)

7.0 英寸 WSVGA(平板电脑)(1024 * 600:mdpi)

normal - hdpi \ dimens.xml

以下设备可以根据更改 normal - hdpi \ dimens.xml 文件来更改屏幕大小

nexus s(4.0英寸,480 * 800:hdpi)

nexus one(3.7英寸,480 * 800:hdpi)

small - ldpi \ dimens.xml

以下设备可以根据更改 small - ldpi \ dimens.xml 文件来更改屏幕大小

2.7 英寸 QVGA 滑盖手机(240 * 320:ldpi)

2.7 英寸 QVGA(240 * 320:ldpi)

xlarge - mdpi \ dimens.xml

以下设备可以根据更改 xlarge - mdpi \ dimens.xml 文件来更改屏幕大小

10.1 英寸 WXGA(平板电脑)(1280 * 800:MDPI)

normal - ldpi \ dimens.xml

以下设备可以根据更改 normal - ldpi \ dimens.xml 文件来更改屏幕大小

3.3 英寸 WQVGA(240 * 400:LDPI)

3.4 英寸 WQVGA(240 * 432:LDPI)

normal-hdpi\dimens.xml

以下设备可以在更改 normal-hdpi\dimens.xml 文件时更改屏幕大小:

4.0 英寸 WVGA(480*800:hdpi)

3.7 英寸 WVGA(480*800:hdpi)

3.7 英寸 FWVGA 滑盖手机(480*854:hdpi)

normal-mdpi\dimens.xml

以下设备可以在更改 normal-mdpi\dimens.xml 文件时更改屏幕大小:

3.2 英寸 HVGA 滑盖手机(ADP1)(320*480:MDPI)

3.2 英寸 QVGA(ADP2)(320*480:MDPI)


那么根据您的意见,文件夹的命名应该类似于 values-normal-xhdpi 吗? - VonSchnauzer
是的,我同意你的观点。我说的是,“为不同的文本大小创建不同的值文件夹”,而不是将值写入所有文件中。所以请仔细阅读标题。谢谢。 - koteswarao
它不起作用。所有设备都从values-xxxhdpi文件夹中获取资源,而不是从values文件夹中获取。对于所有设备,它总是从同一个文件夹中获取值。 - user924

13

有一些非常好的库可以处理所有事情并减少你的痛苦。使用它,只需在 gradle 中添加两个依赖项:

有些好用的库能自动处理所有事情,让你少些麻烦。只需要在 gradle 中添加两个依赖即可:

 implementation 'com.intuit.ssp:ssp-android:1.0.5'
 implementation 'com.intuit.sdp:sdp-android:1.0.5'

在那之后,像这样使用dimens

        android:layout_marginTop="@dimen/_80sdp"

4
以下是参考资料的库:[SDP](https://github.com/intuit/sdp)和[SSP](https://github.com/intuit/ssp)。感谢您提供这个精确的答案! - JorgeAmVF
5
根据现在的时间2020,这也并不完美。 - Kishan Solanki
如果您认为理想的尺寸是5英寸,使用这些库是可以的。 - Vishal Naikawadi

8

您需要为不同的屏幕创建不同的values文件夹,并根据密度放置dimens.xml文件。

1) values

2) values-hdpi (320x480 ,480x800)

3) values-large-hdpi (600x1024)

4) values-xlarge (720x1280 ,768x1280 ,800x1280 ,Nexus7 ,Nexus10)

5) values-sw480dp (5.1' WVGA screen)

6) values-xhdpi (Nexus4 , Galaxy Nexus)

在哪里可以获取屏幕尺寸之间的比率?因为我在工具中看到他们用“ldpi”、“mdpi”的方式定义了所有内容。 - Amit Pal
这将取决于您的values文件夹,它将从中检索值。 - Piyush
我需要在Nexus 6中提到values-xxhdpi吗? - Amit Pal
320x480 是典型的 mdpi。因此,将其放置在 valuesvalues-mdpi 中。 - Phantômaxx
横屏模式怎么样? - sagar suri
它不起作用。所有设备都从values-xxxhdpi文件夹中获取资源,而不是从values文件夹中获取。对于所有设备,它总是从同一个文件夹中获取值。 - user924

8
我已经上传了一个简单的Java程序,它需要你的项目位置和所需的尺寸文件作为输入。根据这个,它会在控制台输出相应的尺寸文件。这是它的链接:https://github.com/akeshwar/Dimens-for-different-screens-in-Android/blob/master/Main.java。以下是完整代码供参考:
public class Main {


    /**
     * You can change your factors here. The current factors are in accordance with the official documentation.
     */
    private static final double LDPI_FACTOR = 0.375;
    private static final double MDPI_FACTOR = 0.5;
    private static final double HDPI_FACTOR = 0.75;
    private static final double XHDPI_FACTOR = 1.0;
    private static final double XXHDPI_FACTOR = 1.5;
    private static final double XXXHDPI_FACTOR = 2.0;

    private static double factor;

    public static void main(String[] args) throws IOException {


        Scanner in = new Scanner(System.in);
        System.out.println("Enter the location of the project/module");
        String projectPath = in.nextLine();

        System.out.println("Which of the following dimension file do you want?\n1. ldpi \n2. mdpi \n3. hdpi \n4. xhdpi \n5. xxhdpi \n6. xxxhdpi");

        int dimenType = in.nextInt();

        switch (dimenType) {
            case 1: factor = LDPI_FACTOR;
                break;
            case 2: factor = MDPI_FACTOR;
                break;
            case 3: factor = HDPI_FACTOR;
                break;
            case 4: factor = XHDPI_FACTOR;
                break;
            case 5: factor = XXHDPI_FACTOR;
                break;
            case 6: factor = XXXHDPI_FACTOR;
                break;
            default:
                factor = 1.0;
        }

        //full path = "/home/akeshwar/android-sat-bothIncluded-notintegrated/code/tpr-5-5-9/princetonReview/src/main/res/values/dimens.xml"
        //location of the project or module = "/home/akeshwar/android-sat-bothIncluded-notintegrated/code/tpr-5-5-9/princetonReview/"


        /**
         * In case there is some I/O exception with the file, you can directly copy-paste the full path to the file here:
         */
        String fullPath = projectPath + "/src/main/res/values/dimens.xml";

        FileInputStream fstream = new FileInputStream(fullPath);
        BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

        String strLine;

        while ((strLine = br.readLine()) != null)   {
            modifyLine(strLine);
        }
        br.close();

    }

    private static void modifyLine(String line) {

        /**
         * Well, this is how I'm detecting if the line has some dimension value or not.
         */
        if(line.contains("p</")) {
            int endIndex = line.indexOf("p</");

            //since indexOf returns the first instance of the occurring string. And, the actual dimension would follow after the first ">" in the screen
            int begIndex = line.indexOf(">");

            String prefix = line.substring(0, begIndex+1);
            String root = line.substring(begIndex+1, endIndex-1);
            String suffix = line.substring(endIndex-1,line.length());


            /**
             * Now, we have the root. We can use it to create different dimensions. Root is simply the dimension number.
             */

            double dimens = Double.parseDouble(root);
            dimens = dimens*factor*1000;
            dimens = (double)((int)dimens);
            dimens = dimens/1000;
            root = dimens + "";

            System.out.println(prefix + " " +  root + " " + suffix );

        }

        System.out.println(line);
    }
}

6
你可以将dimens.xml文件放置在以下文件夹中:
1) values 2) values-hdpi 3) values-xhdpi 4) values-xxhdpi 根据设备的密度,在相应的文件夹中提供不同大小的dimens.xml文件。

3
根据 Android 文档,small/normal/large 已经被弃用。 - Benjamin Mesing
它不起作用,无论哪种设备都从values-xxxhdpi文件夹中获取资源,而不是从values文件夹中获取。 - user924

2
获得更灵活的代码的基本原则是通过封装变化的部分(或者高度可能发生变化的部分)。如果您的案例尺寸正在改变,那么您可以首先将需要更改的尺寸(您认为需要更改的尺寸)从XML代码或Java/Kotlin代码移动到文件值/ dimens.xml中。对于这个问题的上下文,您可以按密度限定符或小宽度限定符来创建res文件夹。
values/dimens.xml
values-ldpi/dimens.xml
values-hdpi/dimens.xml

values/dimens.xml
values-sw320dp/dimens.xml
values-sw320dp/dimens.xml
 

这里需要注意的一个重要点是,values/dimens.xml 中的项目将应用于屏幕尺寸小于您指定的最低断点的情况。
values/dimens.xml //smallest screen
values-sw320dp/dimens.xml //320dp or more till next breakpoint folder
values-sw360dp/dimens.xml//360dp or more till next breakpoint folder

另一个需要注意的重要点是,高像素密度设备可能会有较小的屏幕。因此,请确定您想指定密度限定符还是屏幕宽度限定符。
对于那些新手来说,以下是一些进一步的简介。
您可以向不同的资源文件夹(如值、可绘制和布局)添加限定符。
这些限定符可能代表语言(-en,-hi)、方向(-land,-port)或屏幕尺寸范围(-ldpi,-hdpi)。
命名约定具有限定符的层次结构,并且必须按照该顺序添加限定符。
    values-en-hdpi (it cannot be values-hdpi-en)
    values-en-land-hdpi (it cannot be values values-hdpi-en-land or any other order)
layout-hdpi

订单记录在本页面的表2中。
一些修饰符代表绝对值,而像ldpi、hdpi等的其他修饰符则代表断点。

1
如果您想查看更多内容:这里有一个链接,列出了各种设备(平板电脑、手机、手表),包括watchchromebookwindowsmac。在这里,您可以找到密度、尺寸等信息。如果您使用模拟器,这是一个很好的资源。
如果您点击特定项目,它将在右侧显示更多详细信息。 示例 由于它是Android,我会发布相关内容。 示例1

sample2

最好保存网页的副本以便离线查看。


1
Android 3.2引入了一种新的屏幕尺寸方法,描述屏幕尺寸的数字都是以“dp”为单位。我们可以使用最小宽度dp:应用程序布局中可用的最小宽度,以“dp”为单位;这是您在任何显示旋转中遇到的最小宽度dp。
要创建一个,请右键单击res >>> new >>> Android资源目录
从“可用限定符”窗口将“最小屏幕宽度”移动到“已选择的限定符”
在“屏幕宽度”窗口中,只需编写“dp”值,从您想要Android Studio使用该dimens开始。
然后切换到“项目”视图,右键单击您新创建的资源目录
新>>>值资源文件输入一个新文件名dimens.xml,完成。

感谢您解释如何实际创建这些文件夹。 - Beko

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