【问题标题】:Flutter UI breaks when "smallest width" is changed in developer optionsFlutter UI 在开发人员选项中更改“最小宽度”时中断
【发布时间】:2020-05-29 09:58:07
【问题描述】:

我是 Flutter 编程的新手。我一直在制作如下所示的某个 UI。

如果我尝试更改开发人员选项中的“最小宽度”选项并将其设置为默认值以外的其他值,则整个 UI 会中断,如图所示。

我必须补充一点,完全损坏的中间区域是一个堆栈小部件。

@override
  Widget build(BuildContext context) {
    return Consumer<SinglePlayerGameState>(
      builder: (context, gameState, child) => Expanded(
        flex: 48,
        child: Container(
          color: gameState.getGameColor(),
          child: Center(
            child: Stack(
              overflow: Overflow.visible,
              children: <Widget>[
                Positioned(
                  child: Transform.rotate(
                    angle: 45,
                    child: UNOcard(UNOcardData(CardTypes.BACK)),
                  ),
                  top: -30,
                  left: 90,
                ),
                Positioned(
                  child: Transform.rotate(
                    angle: 65,
                    child: UNOcard(UNOcardData(CardTypes.BACK)),
                  ),
                  top: 20,
                  left: 50,
                ),
                Positioned(
                  child: Transform.rotate(
                    angle: 180,
                    child: UNOcard(UNOcardData(CardTypes.BACK)),
                  ),
                  top: 100,
                  left: 65,
                ),
                Positioned(
                  child: Transform.rotate(
                    angle: 45,
                    child: UNOcard(UNOcardData(CardTypes.BACK)),
                  ),
                  top: 10,
                  right: 10,
                ),
                Positioned(
                  child: Transform.rotate(
                    angle: 65,
                    child: UNOcard(UNOcardData(CardTypes.BACK)),
                  ),
                  top: 120,
                  right: 50,
                ),
                Positioned(
                  child: Container(
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(30),
                        color: Colors.black),
                    child: Text(
                      "${gameState.playingCards.length}",
                      style: TextStyle(
                          fontSize: 20,
                          fontFamily: 'Frijole',
                          color: Colors.white),
                    ),
                    padding: EdgeInsets.all(7),
                  ),
                  top: 10,
                  left: 10,
                ),
                Positioned(
                  child: SizedBox(
                    child: Center(
                        child: FlatButton(
                      onPressed: () {
                        gameState.nextTurn();
                      },
                      child: Icon(
                        FontAwesomeIcons.undoAlt,
                        size: 25,
                      ),
                      color: Colors.white,
                    )),
                    height: 35,
                    width: 60,
                  ),
                  bottom: 10,
                  left: 10,
                ),
                Positioned(
                  child: DragTarget<UNOcardData>(
                    onWillAccept: (UNOcardData data) {
                      var res = isValidMove(
                          data, gameState.onGoingCards.last, gameState);
                      if(res){
                        print(res);
                        return true;
                      }else{
                        vibrate();
                         return false;
                      }
                    },
                    onAccept: (UNOcardData data) {
                      print(data);
                      performAction(data, gameState);
                    },
                    builder: (context, candidateData, rejectedData) =>
                        Transform.rotate(
                      angle: 0,
                      child: gameState.onGoingCards.last,
                    ),
                  ),
                  top: 60,
                  right: 100,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

就像我们在 html/css 中使用“vmin 、 vmax 、 vh ”等单位来表示响应式文本和大小一样,flutter 中有哪些替代方案?我们如何在 Flutter 中准确响应应用程序?我说的不是缩放到其他屏幕尺寸,而是稍微不同的分辨率和逻辑像素密度。

感谢您的宝贵时间。

【问题讨论】:

  • 您可以使用https://pub.dev/packages/auto_size_text 插件来自动调整文本大小。

标签: flutter dart flutter-layout


【解决方案1】:

那是因为你使用了边缘的边距

Positioned(
  child: Transform.rotate(
    angle: 180,
    child: UNOcard(UNOcardData(CardTypes.BACK)),
  ),
  top: 100,
  left: 65,
),

这个顶部意味着它将自己定位到距离顶部 100 个单位的位置。你真正想要的是从中心偏移一些百分比。你可以这样做:

Positioned.fill(
  child: Align(
    // (0, 0) is the center, (1, 1) is right bottom, (-1, -1) is left top and so on
    alignment: Alignment(0.25, 0.25), 
    child: YOUR_WIDGET
  )
);

要获得更具响应性的 UI,您可以使用 MediaQuery.of(context) 获取 screen_sizes 或使用 flutter_screenutil 之类的包来根据示例缩放您的 UI,例如 1080x1920 屏幕。

【讨论】:

  • 从中心安排孩子似乎最合适。
  • 是的,这个 0.25,0.25 意味着小部件将把自己定位在从中心到右下角距离的 1/4 处,应该对所有卡片都这样做,花哨的方式会使用 sin 和 cosin 计算整个小部件列表,但手动方式也可以工作并且可以更快地完成。
猜你喜欢
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2015-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多