Еквівалент wrap_content та match_parent у трепеті?


127

В Android match_parentі wrap_contentвикористовуються для автоматичного зміни розміру віджетів відносно їх батьківського вмісту, який містить віджет.

У Flutter, здається, за замовчуванням всі віджети встановлені на wrap_content, як би я змінив його таким, щоб я міг заповнити його widthта heightтой, який має його батько?

Відповіді:


161

Ви можете зробити з маленьким трюком: припустимо, у вас є вимога: (ширина, висота)

Wrap_content, Wrap_content:

 //use this as child
 Wrap(
  children: <Widget>[*your_child*])

Match_parent, Match_parent:

 //use this as child
Container(
        height: double.infinity,
    width: double.infinity,child:*your_child*)

Match_parent, Wrap_content:

 //use this as child
Row(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[*your_child*],
);

Wrap_content, Match_parent:

 //use this as child
Column(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[your_child],
);

2
щоб відповідати батькові, ви також можете обернути свої віджети за допомогою SizedBox.expand ()
Wecherowski

138

Для того , щоб отримати поведінку для match_parent і wrap_content ми повинні використовувати mainAxisSize властивість в рядки / стовпці віджета, то mainAxisSize властивість приймає MainAxisSize перерахування , що має два значення, є MainAxisSize.min , який веде себе як wrap_content і MainAxisSize.max , який веде себе як match_parent .

введіть тут опис зображення

Посилання первинної статті


6
Я додам, що є також crossAxisAlignmentполе на рядках та стовпцях, яке можна встановити так, CrossAxisAlignment.stretchщоб розширюватись горизонтально в межах стовпця, наприклад
wamfous

1
Дуже дякую! Я проголосував минулого року, тоді я довго не користувався флектом і забув майже все, і ти мені знову допоміг.
Чандлер

33

Коротка відповідь полягає в тому, що батько не має розміру, поки дитина не має розміру.

Те, як працює макет у Flutter, полягає в тому, що кожен віджет забезпечує обмеження для кожного з його дітей, як-от "ти можеш бути таким широким, ти повинен бути таким високим, ти повинен бути принаймні таким широким", або будь-яким іншим (конкретно, вони отримати мінімальну ширину, максимальну ширину, мінімальну висоту та максимальну висоту). Кожна дитина бере ці обмеження, робить щось і вибирає розмір (ширину та висоту), що відповідає цим обмеженням. Потім, як тільки кожна дитина зробить свою справу, віджет може вибрати власний розмір.

Деякі віджети намагаються бути настільки великими, наскільки дозволяє батько. Деякі віджети намагаються бути такими ж маленькими, як дозволяє батько. Деякі віджети намагаються відповідати певному "натуральному" розміру (наприклад, текст, зображення).

Деякі віджети кажуть своїм дітям, що вони можуть бути будь-якого розміру, який вони хочуть. Деякі дають своїм дітям ті самі обмеження, які вони отримали від свого батька.


Ян, коли у мене PageViewвсередині a Column, з іншим Columnвсередині струму page, я отримую помилку візуалізації, але я можу виправити це, обернувши PageViewвсередину Expandedабо a Flexible. Проблема в тому, що ці 2 варіанти лише розширюють свою дитину. Чому для вирішення подібних проблем візуалізації не існує відповідного віджета, який би зменшувався, як-от "обгортання вмісту"?
Мішель Файнштейн

21

Насправді доступні деякі варіанти:

Ви можете використовувати SizedBox.expand, щоб ваш розмір віджетів відповідав розмірам батьків, або SizedBox (ширина: double.infinity), щоб відповідати тільки ширині або SizedBox (heigth: double.infinity), щоб відповідати лише висоті.

Якщо ви хочете поведінку wrap_content, це залежить від батьківського віджета, який ви використовуєте, наприклад, якщо ви кладете кнопку на стовпець, він буде вести себе як wrap_content, а якщо використовувати match_parent, ви можете обернути кнопку розширеним віджетом або розміром.

За допомогою ListView кнопка отримує поведінку match_parent, а для отримання поведінки wrap_content можна обернути її віджетом Flex типу Row.

Використання розширеного віджету робить дочірню рядок, стовпчик або гнучку для розширення, щоб заповнити наявний простір на головній осі (наприклад, горизонтально для рядка або вертикально для стовпця). https://docs.flutter.io/flutter/widgets/Expanded-class.html

Використання гнучкого віджета надає дитині рядка, стовпця або гнучкості для розширення, щоб заповнити наявний простір на головній осі (наприклад, горизонтально для рядка або вертикально для стовпця), але, на відміну від розширеного, гнучка не робить вимагати від дитини заповнити наявний простір. https://docs.flutter.io/flutter/widgets/F prilagod-class.html


7

Просте вирішення:

Якщо контейнер має лише одну дочірню верхівку, то ви можете вказати властивість вирівнювання для дитини та надати їй будь-яке доступне значення. він заповнить весь простір у контейнері.

Container(color:Colors.white,height:200.0,width:200.0,
 child:Container(
    color: Colors.yellow,
    alignment:Alignment.[any_available_option] // make the yellow child match the parent size
   )
)

Інший спосіб:

Container(color:Colors.white,height:200.0,width:200.0,
 child:Container(
    color: Colors.yellow,
    constraints:  BoxConstraints.expand(height: 100.0), // height will be 100 dip and width will be match parent
   )
)

BoxConstraints.expand(height: 100.0)чудово працює як width="match_parent"еквівалент Android
kosiara - Bartosz Kosarzycki

6

Я використовував це рішення, ви повинні визначити висоту та ширину екрана за допомогою MediaQuery:

 Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width
  )

5
Stack(
  children: [
    Container(color:Colors.red, height:200.0, width:200.0),
    Positioned.fill(
      child: Container(color: Colors. yellow),
    )
  ]
),

1
Хоча ваш код може відповісти на питання, хороша відповідь завжди повинна пояснювати, що робить код і як він вирішує проблему.
BDL

це не є відповіддю на завершення вмісту. це просто важко закодована ширина і висота.
Developine

1

Використовуйте віджет Wrap.

Для Columnподібної поведінки спробуйте:

  return Wrap(
          direction: Axis.vertical,
          spacing: 10,
          children: <Widget>[...],);

Для Rowподібної поведінки спробуйте:

  return Wrap(
          direction: Axis.horizontal,
          spacing: 10,
          children: <Widget>[...],);

Для отримання додаткової інформації: Wrap (Flutter Widget)


0

Використовуйте цей рядок кодів усередині стовпця. Для wrap_content: mainAxisSize: MainAxisSize.min для match_parent:mainAxisSize: MainAxisSize.max


0

Насправді це дуже простий і акуратний спосіб зробити це.

Використовуйте FractionallySizedBoxвіджет.

FractionallySizedBox(
  widthFactor: 1.0, // width w.r.t to parent
  heightFactor: 1.0,  // height w.r.t to parent
  child: *Your Child Here*
}

Цей віджет також дуже корисний, коли ви хочете розмістити свою дитину за розміром дробу від її батьків.

Приклад:

Якщо ви хочете, щоб дитина займала 50% ширини свого батька, надайте widthFactorяк0.5


0

Щоб дитина наповнив свого батька, просто загорніть його в FittedBox

    FittedBox(
     child: Image.asset('foo.png'),
     fit: BoxFit.fill,
   )
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.