如何包装按钮并在包装时扩展到父级宽度

how to wrap buttons and expand to parent width on wrap

我想要一个从小屏幕包裹时的响应式扩展按钮。

这是 'emergency contact' 和 'book again' 按钮适合屏幕时的样子:(例如:iPhone 13 Pro Max):

这是 'emergency contact' 和 'book again' 按钮在被包裹且无法适应屏幕时的样子:(例如:iPhone 8):

但是,现在的真实情况是这样的:

代码:

  Container(
                                  margin: const EdgeInsets.only(top: 5),
                                  alignment: Alignment.topLeft,
                                  child: Wrap(
                                    runAlignment: WrapAlignment.start,
                                    runSpacing: 2.5,
                                    spacing: 2.5,
                                    children: [
                                      Expanded(
                                          flex: 1,
                                          child: SizedBox(
                                              child: ElevatedButton(
                                                  style: ElevatedButton
                                                      .styleFrom(
                                                    primary: Colors.white,
                                                  ),
                                                  onPressed: () {
                                                    // ignore: avoid_print
                                                    print("Book Again");
                                                  },
                                                  child: const Text(
                                                    "Book Again",
                                                    style: TextStyle(
                                                        color:
                                                            Colors.black),
                                                  )))),
                                      Expanded(
                                          flex: 1,
                                          child: SizedBox(
                                            child: ElevatedButton(
                                                style: ElevatedButton
                                                    .styleFrom(
                                                        primary:
                                                            Colors.white),
                                                onPressed: () {
                                                  // ignore: avoid_print
                                                  print(
                                                      "Emergency contact");
                                                },
                                                child: const Text(
                                                  "Emergency Contact",
                                                  style: TextStyle(
                                                      color: Colors.black,
                                                      fontSize: 14),
                                                )),
                                          ))
                                    ],
                                  ),
                                )

我尝试在两个 expanded 上使用 Wrap,其中包含一个 sizedbox,其中包含 elevatedbutton

我将不胜感激任何反馈。

Hii Gian Wrap 在这种情况下无法帮助您。您需要使用 Layout Builder 对于这个问题,我已经证明了示例代码。

import 'package:flutter/material.dart';

class IssueWithWrap extends StatefulWidget {
  const IssueWithWrap({Key? key}) : super(key: key);

  @override
  State<IssueWithWrap> createState() => _IssueWithWrapState();
}

class _IssueWithWrapState extends State<IssueWithWrap> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            LayoutBuilder(
              builder: (context, contraints) {
                print(contraints.biggest.width);
                if (contraints.biggest.width > 550) {
                  return Row(
                    children: [
                      Expanded(
                        child: _ExpandableButton(
                          text: "Book Again",
                        ),
                      ),
                      Expanded(
                        child: _ExpandableButton(
                          text: "Emergency Contact",
                        ),
                      ),
                    ],
                  );
                } else {
                  return Column(
                    children: [
                      _ExpandableButton(
                        width: double.infinity,
                        text: "Book Again",
                      ),
                      _ExpandableButton(
                        width: double.infinity,
                        text: "Emergency Contact",
                      ),
                    ],
                  );
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

class _ExpandableButton extends StatelessWidget {
  final String text;
  final double? width;

  const _ExpandableButton({Key? key, required this.text, this.width})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      alignment: Alignment.center,
      decoration: BoxDecoration(
          color: Colors.pink.shade900, borderRadius: BorderRadius.circular(8)),
      child: Text(
        text,
        style: TextStyle(fontSize: 20, color: Colors.white),
      ),
    );
  }
}

我通常使用 LayoutBuilder 和在 Internet 上找到的常量大小以使其响应。

示例:

import 'package:flutter/material.dart';

const i13w = 1284.0; // Big screen (Iphone 13 promax width)
const i8w = 750.0; // Small screen (Iphone 8 width)

void main() => runApp(MaterialApp(home: Scaffold(body: MyApp())));

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: LayoutBuilder(builder: (context, constrains) {
        final w = constrains.maxWidth;
        
        renderAsI13() {
          ...
        }
        renderAsI8() {
          ...
        }

        if (w >= i8w) return renderAsI13(); // If screen size bigger than ip8 size, render as bigger way
        return renderAsI8(); // Or else render as diferences way
      }),
    );
  }
}