【问题标题】:How to pick an asset according to screen density (DPI size)?如何根据屏幕密度(DPI 大小)选择资产?
【发布时间】:2018-12-20 07:45:54
【问题描述】:

我正在尝试根据我的颤振应用程序中的显示密度加载图标。如何根据屏幕密度动态加载(hdpi、xhdpi、xxhdpi..)。

【问题讨论】:

标签: flutter flutter-layout


【解决方案1】:

搜索了几个小时后,根据official documenation,颤振取决于devicePixelRatio,即:

Device Pixel Ratio (DPR) is the relationship between physical 
hardware-based pixels and Device-Independent Pixels which are an abstraction.

对于 Android:

Denisty   Pixel Ratio
mdpi        1.0x
hdpi        1.5x
xhdpi       2.0x
xxhdpi      3.0x
xxxhdpi     4.0x

对于 iOS:

对于颤振:

.../image.png
.../Mx/image.png
.../Nx/image.png
...etc.

其中 M 和 N 是数字标识符,对应于其中包含的图像的标称分辨率。 换句话说,它们指定了图像所针对的设备像素比。

假定主要资产对应于 1.0 的分辨率。例如,考虑以下图片的资产布局

所以这取决于你有多少分辨率来创建你的资产文件夹的不同子目录,所以我的建议是创建以下子目录文件夹来覆盖所有 DPR:

.../image.png  ---> default for android mdpi(1.0x) and ios @1x
.../1.5x/image.png  ---> default for android hdpi(1.5x)
.../2.0x/image.png  ---> default for android xhdpi(2.0x) and ios @2x
.../3.0x/image.png  ---> default for android xxhdpi(3.0x) and ios @3x
.../4.0x/image.png  ---> default for android xxxhdpi(4.0x)

在 Flutter 项目中:

在 pubspec.yaml 中添加默认图片路径:

  assets:
    - assets/images/image.png

如果有人需要使用 SVG,请查看package

SvgPicture.asset(assetName)

【讨论】:

    【解决方案2】:

    Flutter 支持通过自动选择 DPI 相关资源来加载资产,有关该机制的工作原理,请参阅 https://flutter.dev/docs/development/ui/assets-and-images#resolution-aware

    Flutter 应该根据 devicePixelRatio 值缩放文本。这是一个示例应用程序,向您展示了它是如何工作的:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
      MediaQueryData queryData;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        queryData = MediaQuery.of(context);
        double devicePixelRatio = queryData.devicePixelRatio;
        TextStyle style38 = new TextStyle(
          inherit: true,
          fontSize: 38.0,
        );
        TextStyle style20 = new TextStyle(
          inherit: true,
          fontSize: 20.0,
        );
        return new Scaffold(
          appBar: new AppBar(
            title: new Text(widget.title),
          ),
          body: new Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              new Text(
                'Button tapped $_counter time${ _counter == 1 ? '' : 's' }.',
                style: style38,
              ),
              new Text(
                'size (pixels): w=${queryData.size.width * devicePixelRatio}, h=${queryData.size.height * devicePixelRatio}',
                style: style20,
              ),
              new Text(
                'devicePixelRatio: $devicePixelRatio',
                style: style20,
              ),
              new Text(
                'size: w=${queryData.size.width}, h=${queryData.size.height}',
                style: style20,
              ),
              new Text(
                'textScaleFactor: w=${queryData.textScaleFactor}',
                style: style20,
              ),
            ],
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: new Icon(Icons.add),
          ),
        );
      }
    }
    

    它是默认 Flutter 应用程序的修改版本,显示设备视口大小(以像素为单位)、devicePixelRatio 值、以绝对像素为单位的大小。查看应用程序在 Android 上以 3 种不同分辨率运行的屏幕截图,然后是 iPhone 7 Plus 屏幕分辨率的 iOS 模拟器。屏幕分辨率为:

    1. Android 1440 x 2560,devicePixelRatio:3.5
    2. Android 1080 x 1920,devicePixelRatio:2.625
    3. Android 720 x 1280,devicePixelRatio:1.75
    4. iOS 模拟器 1080 x 1920 (iPhone 7 Plus), devicePixelRatio: 3.0

    所有设备上的文字都根据实际屏幕尺寸和逻辑视口进行缩放。

    Android 1440 x 2560,设备像素比率:3.5

    ets-and-images/#declaring-resolution-aware-image-assets

    【讨论】:

    • 很好的解释!,奇怪的是链接在点击时不起作用,但在浏览器中手动粘贴时起作用
    猜你喜欢
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 2017-05-26
    • 2023-03-26
    相关资源
    最近更新 更多