【问题标题】:Universal UI layout on flutter for screens of different sizesFlutter 上的通用 UI 布局,适用于不同尺寸的屏幕
【发布时间】:2021-03-05 23:51:09
【问题描述】:

我是颤振初学者。我正在阅读文档并尝试一下。对不起,我的谷歌英语。


我有一个小应用程序。问题是它在不同的屏幕上看起来不同。


注意!我了解通用布局的问题,并且已经阅读了原始 Flutter 文档为我提供的解决不同屏幕问题的内容。


基本上,我被要求使用 MediaQuery.of () 定义屏幕边框,并将其限制为 800 等参数。 问题是我对文本使用字体大小参数,并且我的按钮会定期丢失其中的文本,或者如果我没有在 LITERALLY EACH 元素上使用 MediaQuery.of () 添加大量检查,它们就会变得太小。 难道我真的要使用MediaQuery.of()。每个对象的 Size.width?没有其他解决方案吗?在我看来,这非常麻烦和不方便。也许我误解了提供给我的响应式应用程序的概念。

【问题讨论】:

  • 嗨,您可能想提供代码示例,您到目前为止所做的工作,以便为我们提供上下文以获得更好的响应。
  • @YamaçKurtuluş,这就是我的意思:fontSize: MediaQuery.of(context).size.height
  • @YamaçKurtuluş 容器大小、字体大小等。我真的不明白,我应该使用屏幕尺寸的百分比吗?像 (MediaQuery.of().size.width / (any number)) 之类的东西?或者怎么做?
  • TLDR:这个话题有点宽泛,如果我们要讨论它,可能需要相当长的时间。您可以有一个 if-else 条件来首先检查屏幕尺寸并确定您想要将其赋予文本的尺寸。这是一个可能对你有帮助的 Flutter 包。 pub.dev/packages/auto_size_text 不过不推荐这种方式....

标签: android flutter user-interface flutter-layout


【解决方案1】:

不需要包裹。我创建了与这个包相同的 https://pub.dev/packages/flutter_screenutil

我在生产应用程序中使用它。

import 'dart:ui' as ui;

import 'package:flutter/material.dart';

class Responsiveness {
  static Responsiveness _instance;
  static const Size defaultSize = Size(375, 812);

  Size uiSize = defaultSize;

  bool allowFontScaling;

  static double _screenWidth;
  static double _screenHeight;
  static double _pixelRatio;
  static double _statusBarHeight;
  static double _bottomBarHeight;
  static double _textScaleFactor;

  Responsiveness._() {
    MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
    _pixelRatio = mediaQuery.devicePixelRatio;
    _screenWidth = mediaQuery.size.width;
    _screenHeight = mediaQuery.size.height;
    _statusBarHeight = mediaQuery.padding.top;
    _bottomBarHeight = mediaQuery.padding.bottom;
    _textScaleFactor = mediaQuery.textScaleFactor;
  }

  factory Responsiveness() {
    assert(
      _instance != null,
      '\nEnsure to initialize Responsiveness before accessing it.',
    );
    return _instance;
  }

  static void init({
    Size designSize = defaultSize,
    bool allowFontScaling = false,
  }) {
    _instance ??= Responsiveness._();
    _instance
      ..uiSize = designSize
      ..allowFontScaling = allowFontScaling;
  }

  static double get textScaleFactor => _textScaleFactor;

  /// The size of the media in logical pixels (e.g, the size of the screen).
  static double get pixelRatio => _pixelRatio;

  /// The horizontal extent of this size.
  static double get screenWidth => _screenWidth;

  /// The vertical extent of this size. dp
  static double get screenHeight => _screenHeight;

  /// The vertical extent of this size. px
  static double get screenWidthPx => _screenWidth * _pixelRatio;

  /// The vertical extent of this size. px
  static double get screenHeightPx => _screenHeight * _pixelRatio;

  /// The offset from the top
  static double get statusBarHeight => _statusBarHeight;

  /// The offset from the bottom.
  static double get bottomBarHeight => _bottomBarHeight;

  /// The ratio of the actual dp to the design draft px
  double get scaleWidth => _screenWidth / uiSize.width;

  double get scaleHeight =>
      (_screenHeight - _statusBarHeight - _bottomBarHeight) / uiSize.height;

  double get scaleText => scaleWidth;

  /// Adapted to the device width of the UI Design.
  /// Height can also be adapted according to this to ensure no deformation ,
  /// if you want a square
  num setWidth(num width) => width * scaleWidth;

  /// Highly adaptable to the device according to UI Design
  /// It is recommended to use this method to achieve a high degree of adaptation
  /// when it is found that one screen in the UI design
  /// does not match the current style effect, or if there is a difference in shape.
  num setHeight(num height) => height * scaleHeight;

  num setSpacing(num spacing) => spacing * scaleWidth;

  num setHorizontalSpacing(num spacing) => spacing * scaleWidth;

  num setVerticalSpacing(num spacing) => spacing * scaleHeight;

  /// Icon sizing function
  num setIconSize(num size) => size * scaleWidth;

  ///@param [fontSize]
  ///Font size adaptation method
  ///@param [fontSize] The size of the font on the UI design, in px.
  ///@param [allowFontScaling]
  num setFontSize(num fontSize, {bool allowFontScalingSelf}) =>
      allowFontScalingSelf == null
          ? (allowFontScaling
              ? (fontSize * scaleText)
              : ((fontSize * scaleText) / _textScaleFactor))
          : (allowFontScalingSelf
              ? (fontSize * scaleText)
              : ((fontSize * scaleText) / _textScaleFactor));
}

extension ResponsivenessExtension on num {
  // shorthand for width
  num get w => Responsiveness().setWidth(this);

  // shorthand for height
  num get h => Responsiveness().setHeight(this);

  // shorthand for fontsize
  num get f => Responsiveness().setFontSize(this);

  // shorthand for spacing(Padding, margin)
  num get s => Responsiveness().setSpacing(this);

  // shorthand for spacing(Vertical Padding, Vertical margin)
  num get vs => Responsiveness().setVerticalSpacing(this);

  // shorthand for spacing(Horizontal Padding, Horizontal margin)
  num get hs => Responsiveness().setHorizontalSpacing(this);

  // shorthand for icon size
  num get ics => Responsiveness().setIconSize(this);
}

main.dart中初始化

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Responsiveness.init();
  runApp(MaterialApp(home: MyApp(),));
}

any widgetlike中使用

class MyApp extends StatelessWidget {
 @override
  Widget build(BuildContext context) {
    return Container(
      width: 120.w,
      height: 120.h,
      padding: EdgeInsets.all(10.s),
      child: Text(
        'hai', 
        style: TextStyle(fontSize: 12.f,),
      ),
    );
  }
}

注意:.w、.h、.f、.s 是在Responsiveness 中创建的扩展名

为了进一步控制,您可以使用

import 'package:flutter/material.dart';

/// The is a generic widget, used for determining the screen sizes (mobile or desktop)
/// isSmallScreen and isLargeScreen are the functions to decide the width of screen

class ResponsiveLayout extends StatelessWidget {
  /// variable to be used for desktop view
  final Widget largeScreen;

  /// variable to be used for mobile view
  final Widget smallScreen;

  const ResponsiveLayout({
    Key key,
    @required this.largeScreen,
    this.smallScreen,
  }) : super(key: key);

  //static double desktopSize based on screenSize 
  static double desktopSize(context) {
    return (MediaQuery.of(context).size.width>1200)? 1140:970;
  }

  static bool isSmallScreen(BuildContext context) {
    return MediaQuery.of(context).size.width < 992;
  }

  static bool isLargeScreen(BuildContext context) {
    return MediaQuery.of(context).size.width >= 992;
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth >= 992) {
          return largeScreen;
        } else {
          return smallScreen ?? largeScreen;
        }
      },
    );
  }
}

【讨论】:

    猜你喜欢
    • 2017-12-11
    • 2014-09-11
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多