我设置 android 应用维度的方法是否正确?

Is my method to set up android apps dimensions correct?

我使用 Android 工作室作为开发环境,我设置 android 应用程序维度的方法是这样的:

1- 我基于 Android Studio 提供的 Nexus S 为 hdpi 设备创建布局。

2- 我将所有尺寸(使用 dp 和 sp 单位)放在 values-hdpi 文件夹中。

3- 我从这个文件夹中复制了 9 个副本,并将它们重命名如下:

  1. 值-420dpi
  2. 值-560dpi
  3. 值-ldpi
  4. 值-mdpi
  5. 值-sw480dp
  6. 值-sw600dp
  7. 值-sw720dp
  8. 值-xhdpi
  9. 值-xxhdpi

4- 之后,我打开要配置其尺寸的布局文件,然后 select 以下内容:

  1. 420dpi 的 Nexus 5X
  2. Nexus 6P 560dpi
  3. 2.7" 用于 ldpi 的 QVGA
  4. 3.2" QVGA 用于 mdpi
  5. 5.4" FWVGA 用于 sw480dp
  6. Nexus 7 适用于 sw600dp
  7. Nexus 9 适用于 sw720dp
  8. xhdpi 的 Nexus 4
  9. xxhdpi 的 Nexus 5

5- 我开始更改每个文件的尺寸,直到布局适合 selected 设备。

这是我设置 android 应用维度的方法,我想知道它是否正确?如果存在另一种方法可以轻松地做同样的事情?

您应该只使用一种类型的选择器。例如,在您的情况下:

  1. values-sw420dp
  2. values-sw480dp
  3. values-sw560dp
  4. values-sw600dp
  5. values-sw720dp

应该足够了(但显然这取决于应用程序的要求和您想要完全支持的设备)。你为什么还使用 density-based 选择器(比如 values-mdpi)?您可能知道,dpsp 维度与密度无关。

值得补充的是,如果您仔细设计布局,则可以大大减少需要显式声明的维数。例如,您可以将 LinearLayout 用于已称重的儿童。

在复杂的项目中,当我希望应用随屏幕尺寸缩放时,我通常使用脚本从参考文件开始生成所有尺寸文件,将所需的乘数应用于每个屏幕 class .实际代码在很大程度上取决于您的具体需求,但 Java 中的示例可能是:

public class GenerateDimens {

    public static void main(String[] args) throws Exception {
        String resFolder = "app/src/main/res/";
        String dimensFileName = "dimens.xml";
        File source = new File(resFolder + "values-sw800dp", dimensFileName);
        File target = new File(resFolder + "values-sw0dp", dimensFileName);
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document document = builder.parse(source);
        NodeList nodeList = document.getElementsByTagName("dimen");
        Pattern pattern = Pattern.compile("(\d+).*");
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node dimen = nodeList.item(i);
            String textContent = dimen.getTextContent();
            Matcher matcher = pattern.matcher(textContent);
            if (matcher.find()) {
                String oldValue = matcher.group(1);
                String newValue = String.valueOf((int) (Integer.parseInt(oldValue) / 1.33));
                dimen.setTextContent(textContent.replaceFirst(oldValue, newValue));
            }
        }
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
        document.setXmlStandalone(true);
        transformer.transform(new DOMSource(document), new StreamResult(target));
    }

}