简体   繁体   English

有没有办法让 Flutter 中的小部件接近像素完美缩放?

[英]Is there a way to get near pixel perfect scaling of widgets in Flutter?

For my use-case I need layout to be consistently same at different screen widths.对于我的用例,我需要布局在不同的屏幕宽度下保持一致。

For this I'm using a simple scale by reference and multiplying each widget's height by this scale value.为此,我使用了一个简单的参考比例,并将每个小部件的高度乘以这个比例值。 However, the fidelity of the placement is not very accurate, or varies wildly on different screen sizes.但是,放置的保真度不是很准确,或者在不同的屏幕尺寸上变化很大。 I suspect it is to do with the limitation of Flutters logical pixels which are said to be about 38 per centimeter.我怀疑这与 Flutters 逻辑像素的限制有关,据说约为每厘米 38 个。 Especially on small screens (pretty much any mobile) that is not enough to get even close to pixel perfection, and especially text alignments are suffering.尤其是在小屏幕(几乎任何移动设备)上,这还不足以接近像素完美,尤其是文本对齐受到影响。

gif showing the problem gif显示问题

Test code: run on desktop and change the width of the app to see how the margin between the texts jump up and down as if it's snapping the widgets to closest logical pixel.测试代码:在桌面上运行并更改应用程序的宽度,以查看文本之间的边距如何上下跳跃,就好像它将小部件捕捉到最接近的逻辑像素一样。 And the same goes for the text's own bounding box, making the issue worse in case the texts snap in opposite directions:文本自己的边界框也是如此,如果文本以相反的方向对齐,问题就会变得更糟:

import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {

  double getScale(BuildContext context) {
    const double referenceWidth = 400;
    double screenWidth = MediaQuery.of(context).size.width;
    double fraction = screenWidth / referenceWidth;
    return fraction;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Text1',
                style: TextStyle(
                  fontSize: 14 * getScale(context),
                  backgroundColor: Colors.green,
                )
            ),
            Text(
              "text2",
              style: TextStyle(
                fontSize: 14 * getScale(context),
                backgroundColor: Colors.red,
              )
            ),
          ],
        ),
      ),
    );
  }
}

I've tried wrapping in a Transform.scale but it gives the same result in addition to lower quality visuals.我试过用 Transform.scale 包装,但除了质量较低的视觉效果外,它给出了相同的结果。

Am I missing something obvious?我错过了一些明显的东西吗?

EDIT: It seems like the responsive_framework library partially fixes the proiblem: Margin between the widgets to be scaled properly.编辑:似乎 responsive_framework 库部分修复了问题:要正确缩放的小部件之间的边距。 But the Texts still vary their position within their Text widgets.但是文本仍然在它们的文本小部件中改变它们的 position。 I can't figure out why this works though.我不知道为什么这有效。

not sure its exactly pixel perfect but I've managed to get it looking smoother using the Sizer package不确定它的像素是否完美,但我已经设法使用Sizer package 让它看起来更平滑

See gif example参见 gif 示例

import 'package:flutter/material.dart';
import 'package:sizer/sizer.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Sizer(builder: (context, orientation, deviceType) {
      return const MaterialApp(
        home: MyHomePage(),
      );
    });
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: LayoutBuilder(builder: (context, constraints) {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Text1',
                  style: TextStyle(
                    fontSize: 14.w,
                    backgroundColor: Colors.green,
                  )),
              Text("text2",
                  style: TextStyle(
                    fontSize: 14.w,
                    backgroundColor: Colors.red,
                  )),
            ],
          ),
        );
      }),
    );
  }
}

you can use responsive_framwork .你可以使用responsive_framework It'll give pixel perfect ui.它会给像素完美的用户界面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM