[ПЕРЕВОД] Палкая макет памятки

внешний интерфейс Программа перевода самородков Android iOS Flutter

Вам нужно знать о простых шаблонах макетов Flutter? Теперь я покажу вам коллекцию фрагментов кода макета Flutter, которые я обобщил. Я постараюсь, чтобы код был коротким и простым для понимания, и я дам визуализацию. Но нам все равно нужно идти шаг за шагом — каталог шаблонов будет следовать постепенно. Я больше сосредоточусь на применении виджетов Flutter, а не просто на отображении виджетов (Flutter GalleryМолодец на этом этапе! ) Если у вас есть другие вопросы о макетах Flutter или вы хотите поделиться своим кодом, напишите мне!


содержание

  • Строка и столбец
  • Внутренняя ширина и внутренняя высота
  • Stack
  • Expanded
  • ConstrainedBox
  • Container
    • Украшение (украшение): Boxdecormation
    • Изображение (изображение): DecorationImage
    • Граница (граница): Граница
    • Радиус границы (borderRadius): BorderRadius
    • Форма: Боксформа
    • Тень (boxShadow):List<BoxShadow>
    • Градиент (градиент): RadialGradient
    • Режим наложения фона (backgroundBlendMode): BlendMode
  • SizedBox
  • SafeArea

Строка и столбец

MainAxisAlignment

Row /*或 Column*/( 
  mainAxisAlignment: MainAxisAlignment.start,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  mainAxisAlignment: MainAxisAlignment.end,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Если вы хотите базовое выравнивание разных символов, вы должны использоватьCrossAxisAlignment.baseline.

Row(
  crossAxisAlignment: CrossAxisAlignment.baseline,
  textBaseline: TextBaseline.alphabetic,
  children: <Widget>[
    Text(
      'Baseline',
      style: Theme.of(context).textTheme.display3,
    ),
    Text(
      'Baseline',
      style: Theme.of(context).textTheme.body1,
    ),
  ],
),

CrossAxisAlignment

Row /*或 Column*/( 
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 200),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  crossAxisAlignment: CrossAxisAlignment.center,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 200),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  crossAxisAlignment: CrossAxisAlignment.end,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 200),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 200),
    Icon(Icons.star, size: 50),
  ],
),

MainAxisSize

Row /*或 Column*/( 
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Row /*或 Column*/( 
  mainAxisSize: MainAxisSize.min,
  children: <Widget>[
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

Внутренняя ширина и внутренняя высота

Хотите, чтобы все виджеты в строке или столбце имели ту же высоту/ширину, что и самый высокий/широкий виджет? Не ищите, ответ здесь!

Когда у вас есть этот стиль макета:

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('IntrinsicWidth')),
    body: Center(
      child: Column(
        children: <Widget>[
          RaisedButton(
            onPressed: () {},
            child: Text('Short'),
          ),
          RaisedButton(
            onPressed: () {},
            child: Text('A bit Longer'),
          ),
          RaisedButton(
            onPressed: () {},
            child: Text('The Longest text button'),
          ),
        ],
      ),
    ),
  );
}

Но вы хотите, чтобы все кнопки исамый широкийкнопка и т.д.ширина, просто используйтеIntrinsicWidth:

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('IntrinsicWidth')),
    body: Center(
      child: IntrinsicWidth(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            RaisedButton(
              onPressed: () {},
              child: Text('Short'),
            ),
            RaisedButton(
              onPressed: () {},
              child: Text('A bit Longer'),
            ),
            RaisedButton(
              onPressed: () {},
              child: Text('The Longest text button'),
            ),
          ],
        ),
      ),
    ),
  );
}

Если все, что вам нужно, это иметь все детали исамая высокая частьЖдатьвысоко, который можно комбинировать сIntrinsicHeightа такжеRowчасть.


Stack

Отлично подходит для укладки деталей вместе

@override
Widget build(BuildContext context) {
  Widget main = Scaffold(
    appBar: AppBar(title: Text('Stack')),
  );

  return Stack(
    fit: StackFit.expand,
    children: <Widget>[
      main,
      Banner(
        message: "Top Start",
        location: BannerLocation.topStart,
      ),
      Banner(
        message: "Top End",
        location: BannerLocation.topEnd,
      ),
      Banner(
        message: "Bottom Start",
        location: BannerLocation.bottomStart,
      ),
      Banner(
        message: "Bottom End",
        location: BannerLocation.bottomEnd,
      ),
    ],
  );
}

Если вы хотите использовать свои собственные части, вам нужно поместить их вPositionedв

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Stack')),
    body: Stack(
      fit: StackFit.expand,
      children: <Widget>[
        Material(color: Colors.yellowAccent),
        Positioned(
          top: 0,
          left: 0,
          child: Icon(Icons.star, size: 50),
        ),
        Positioned(
          top: 340,
          left: 250,
          child: Icon(Icons.call, size: 50),
        ),
      ],
    ),
  );
}

Если вы не хотите угадывать верхние или нижние значения, вы можете использоватьLayoutBuilderчтобы получить их

Widget build(BuildContext context) {
  const iconSize = 50;
  return Scaffold(
    appBar: AppBar(title: Text('Stack with LayoutBuilder')),
    body: LayoutBuilder(
      builder: (context, constraints) =>
        Stack(
          fit: StackFit.expand,
          children: <Widget>[
            Material(color: Colors.yellowAccent),
            Positioned(
              top: 0,
              child: Icon(Icons.star, size: iconSize),
            ),
            Positioned(
              top: constraints.maxHeight - iconSize,
              left: constraints.maxWidth - iconSize,
              child: Icon(Icons.call, size: iconSize),
            ),
          ],
        ),
    ),
  );
}

Expanded

Expandedможет иFlex\FlexboxМакеты работают вместе и отлично подходят для выделения места для нескольких элементов.

Row(
  children: <Widget>[
    Expanded(
      child: Container(
        decoration: const BoxDecoration(color: Colors.red),
      ),
      flex: 3,
    ),
    Expanded(
      child: Container(
        decoration: const BoxDecoration(color: Colors.green),
      ),
      flex: 2,
    ),
    Expanded(
      child: Container(
        decoration: const BoxDecoration(color: Colors.blue),
      ),
      flex: 1,
    ),
  ],
),

ConstrainedBox

По умолчанию большинство компонентов занимают как можно меньше места:

Card(child: const Text('Hello World!'), color: Colors.yellow)

ConstrainedBoxРазрешить виджету использовать желаемое оставшееся пространство.

ConstrainedBox( 
  constraints: BoxConstraints.expand(),
  child: const Card(
    child: const Text('Hello World!'), 
    color: Colors.yellow,
  ), 
),

вы можете использоватьBoxConstraintsУкажите, сколько места может занимать виджет, указавheight/widthизmin/maxАтрибуты.

BoxConstraints.expandПозволит компоненту использовать неограниченное (все доступное) пространство, если не указано иное:

ConstrainedBox(
  constraints: BoxConstraints.expand(height: 300),
  child: const Card(
    child: const Text('Hello World!'), 
    color: Colors.yellow,
  ),
),

Приведенный выше код эквивалентен следующему коду:

ConstrainedBox(
  constraints: BoxConstraints(
    minWidth: double.infinity,
    maxWidth: double.infinity,
    minHeight: 300,
    maxHeight: 300,
  ),
  child: const Card(
    child: const Text('Hello World!'), 
    color: Colors.yellow,
  ),
),

Container

Один из наиболее часто используемых виджетов — и есть причина, по которой он так распространен:

Контейнер для инструментов компоновки

если вы не укажетеContainerизheightа такжеwidth, это будет иchildтот же размер

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Container as a layout')),
    body: Container(
      color: Colors.yellowAccent,
      child: Text("Hi"),
    ),
  );
}

Если хочешьContainerрасширяется, чтобы быть равным его родительскому элементу, даheightа такжеwidthиспользование собственностиdouble.infinity

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Container as a layout')),
    body: Container(
      height: double.infinity,
      width: double.infinity,
      color: Colors.yellowAccent,
      child: Text("Hi"),
    ),
  );
}

Оформление контейнера

Вы можете использовать свойство цвета, чтобы изменитьContainerцвет фона, ноdecorationа такжеforegroundDecorationвы можете сделать больше. (Используя эти два свойства, вы можете полностью изменитьContainerВнешний вид этой части, о котором я расскажу в продолжении, так как в этой части очень много контента)decorationвсегда ставится после дочернего элемента, аforegroundDecorationзатем вchildнад.

decoration

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Container.decoration')),
    body: Container(
      height: double.infinity,
      width: double.infinity,
      decoration: BoxDecoration(color: Colors.yellowAccent),
      child: Text("Hi"),
    ),
  );
}

decoration and foregroundDecoration

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Container.foregroundDecoration')),
    body: Container(
      height: double.infinity,
      width: double.infinity,
      decoration: BoxDecoration(color: Colors.yellowAccent),
      foregroundDecoration: BoxDecoration(color: Colors.red.withOpacity(0.5)),
      child: Text("Hi"),
    ),
  );
}

Трансформация контейнера

Если вы не хотите использоватьTransformвиджет для изменения макета, вы можете использоватьContainerизtransformАтрибуты

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Container.transform')),
    body: Container(
      height: 300,
      width: 300,
      transform: Matrix4.rotationZ(pi / 4),
      decoration: BoxDecoration(color: Colors.yellowAccent),
      child: Text(
        "Hi",
        textAlign: TextAlign.center,
      ),
    ),
  );
}

BoxDecoration

Декоративные эффекты часто используются в компонентах-контейнерах для изменения внешнего вида компонента.

Изображение (изображение): DecorationImage

Использовать изображение в качестве фона:

Scaffold(
  appBar: AppBar(title: Text('image: DecorationImage')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        color: Colors.yellow,
        image: DecorationImage(
          fit: BoxFit.fitWidth,
          image: NetworkImage(
            'https://flutter.io/images/catalog-widget-placeholder.png',
          ),
        ),
      ),
    ),
  ),
);

Граница (граница): Граница

Задает стиль границы контейнера.

Scaffold(
  appBar: AppBar(title: Text('border: Border')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        color: Colors.yellow,
        border: Border.all(color: Colors.black, width: 3),
      ),
    ),
  ),
);

Радиус границы (borderRadius): BorderRadius

Пусть границы будут закруглены.

если украшенshapeдаBoxShape.circle,ТакborderRadiusбудет недействительным

Scaffold(
  appBar: AppBar(title: Text('borderRadius: BorderRadius')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
          color: Colors.yellow,
          border: Border.all(color: Colors.black, width: 3),
          borderRadius: BorderRadius.all(Radius.circular(18))),
    ),
  ),
);

Форма: Боксформа

Форма коробки может быть прямоугольником, квадратом, эллипсом или кругом.

Для других произвольных форм вы должны использоватьShapeDecorationвместоBoxDecoration

Scaffold(
  appBar: AppBar(title: Text('shape: BoxShape')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        color: Colors.yellow,
        shape: BoxShape.circle,
      ),
    ),
  ),
);

Тень (boxShadow):List<BoxShadow>

Тени могут быть добавлены к контейнерам.

Этот параметр представляет собой список, поэтому вы можете определить несколько различных оттенков, а затем сгруппировать их вместе.

Scaffold(
  appBar: AppBar(title: Text('boxShadow: List<BoxShadow>')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        color: Colors.yellow,
        boxShadow: const [
          BoxShadow(blurRadius: 10),
        ],
      ),
    ),
  ),
);

градиент

Существует три типа градиентов:LinearGradient,RadialGradientа такжеSweepGradient.

`LinearGradient`

Scaffold(
  appBar: AppBar(title: Text('gradient: LinearGradient')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: const [
            Colors.red,
            Colors.blue,
          ],
        ),
      ),
    ),
  ),
);

RadialGradient

Scaffold(
  appBar: AppBar(title: Text('gradient: RadialGradient')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        gradient: RadialGradient(
          colors: const [Colors.yellow, Colors.blue],
          stops: const [0.4, 1.0],
        ),
      ),
    ),
  ),
);

SweepGradient

Scaffold(
  appBar: AppBar(title: Text('gradient: SweepGradient')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        gradient: SweepGradient(
          colors: const [
            Colors.blue,
            Colors.green,
            Colors.yellow,
            Colors.red,
            Colors.blue,
          ],
          stops: const [0.0, 0.25, 0.5, 0.75, 1.0],
        ),
      ),
    ),
  ),
);

Режим наложения фона (backgroundBlendMode)

backgroundBlendModeдаBoxDecorationСамое сложное свойство в . это можно смешатьBoxDecorationцвета и градиенты, и независимо отBoxDecorationНа каких элементах.

имеютbackgroundBlendMode,вы можете использоватьBlendModeДлинный список алгоритмов в перечислимом типе.

Сначала настройтеBoxDecorationдляforegroundDecoration, который отображается вContainerДочерний элемент выше (иdecorationотображается после дочерних элементов).

Scaffold(
  appBar: AppBar(title: Text('backgroundBlendMode')),
  body: Center(
    child: Container(
      height: 200,
      width: 200,
      foregroundDecoration: BoxDecoration(
        backgroundBlendMode: BlendMode.exclusion,
        gradient: LinearGradient(
          colors: const [
            Colors.red,
            Colors.blue,
          ],
        ),
      ),
      child: Image.network(
        'https://flutter.io/images/catalog-widget-placeholder.png',
      ),
    ),
  ),
);

backgroundBlendModeвлияет не только наContainer.

backgroundBlendModeможет измениться сContainerЦвет любого виджета в дереве виджетов. В следующем коде есть родительский элементContainer, который отображает изображениеimageи один б/уbackgroundBlendModeдочерний элементContainer. Вы по-прежнему получите тот же эффект, что и в предыдущем фрагменте кода.

Scaffold(
  appBar: AppBar(title: Text('backgroundBlendMode')),
  body: Center(
    child: Container(
      decoration: BoxDecoration(
        image: DecorationImage(
          image: NetworkImage(
            'https://flutter.io/images/catalog-widget-placeholder.png',
          ),
        ),
      ),
      child: Container(
        height: 200,
        width: 200,
        foregroundDecoration: BoxDecoration(
          backgroundBlendMode: BlendMode.exclusion,
          gradient: LinearGradient(
            colors: const [
              Colors.red,
              Colors.blue,
            ],
          ),
        ),
      ),
    ),
  ),
);

SizedBox

Это самый простой, но самый полезный виджет

SizeBox используется как ConstrainedBox

SizedBoxможет быть достигнуто иConstrainedBoxаналогичный эффект

SizedBox.expand(
  child: Card(
    child: Text('Hello World!'),
    color: Colors.yellowAccent,
  ),
),

SizeBox используется в качестве заполнения

Если вам нужно добавить отступы или поля, вы можете выбратьPaddingилиContainerчасть. Но они не так хороши, как добавлениеSizedboxлегко читать

Column(
  children: <Widget>[
    Icon(Icons.star, size: 50),
    const SizedBox(height: 100),
    Icon(Icons.star, size: 50),
    Icon(Icons.star, size: 50),
  ],
),

SizedBox используется как невидимый объект

Много раз вы хотите передать логическое значение (bool) для управления отображением и скрытием компонентов

Widget build(BuildContext context) {
  bool isVisible = ...
  return Scaffold(
    appBar: AppBar(
      title: Text('isVisible = $isVisible'),
    ),
    body: isVisible 
      ? Icon(Icons.star, size: 150) 
      : const SizedBox(),
  );
}

из-заSizedBoxесть одинconstконструктор, использоватьconst SizedBox()становится очень простым.

Более простым решением является использованиеOpacityкомпоненты, а затемopacityизменить значение на0.0. Недостаток этого решения в том, что хотя компонент и невидим, он все равно занимает место.


SafeArea

На разных платформах есть много специальных позиций, таких как строка состояния системы Android или «обрезанная челка» iPhone X, и нам следует избегать размещения элементов в этих позициях.

Решение заключается в использованииSafeAreaкомпоненты (следующие примеры используются и не используютсяSafeAreaЭффект)

Widget build(BuildContext context) {
  return Material(
    color: Colors.blue,
    child: SafeArea(
      child: SizedBox.expand(
        child: Card(color: Colors.yellowAccent),
      ),
    ),
  );
}

Ждем больше контента

Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.