Flutter - виджет стека
Виджет Stack - это встроенный виджет в SDK flutter, который позволяет нам создавать слой виджетов, помещая их друг на друга. Часто простой разметки строк и столбцов недостаточно, нам нужен способ наложить один виджет поверх другого, например, мы можем захотеть показать текст поверх изображения, поэтому для решения такой ситуации у нас есть Виджет стека. Стек виджетов имеет два типа ребенок один позиционируется , которые обернуты в Позиционируется виджета , а другая не являются - позиционируется который не заключен в виджет Positioned. Для всех непозиционированных виджетов свойство выравнивания устанавливается в верхний левый угол. Позиционированные дочерние виджеты позиционируются через свойства top , right , left и bottom. Дочерние виджеты Stack печатаются в том порядке, в котором самый верхний виджет становится самым нижним на экране и наоборот. Мы можем использовать ключевое свойство виджета Stack, чтобы изменить этот порядок или назначить другой порядок.
Конструктор класса Stack:
Куча( {Key key, Выравнивание AlignmentGeometry: AlignmentDirectional.topStart, TextDirection textDirection, StackFit fit: StackFit.loose, Переполнение переполнения: Overflow.clip, Clip clipBehavior: Clip.hardEdge, Список дочерних элементов <Widget>: const <Widget> []} )
Свойства виджета стека:
- alignment: это свойство принимает параметр геометрии выравнивания и управляет тем, как дочерний виджет, который не позиционируется или частично позиционируется, будет выровнен в стеке .
- clipBehaviour: это свойство определяет, будет ли контент обрезаться или нет.
- fit: это свойство определяет, как непозиционированные дочерние элементы в Stack будут заполнять доступное для него пространство.
- overflow: это свойство контролирует, будет ли видимая часть содержимого при переполнении,
- textDirection: с помощью этого свойства мы можем выбрать направление текста справа налево. или слева направо.
Пример 1:
Дротик
import 'package:flutter/material.dart' ; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: Text( 'GeeksforGeeks' ), backgroundColor: Colors.greenAccent[400], ), //AppBar body: Center( child: SizedBox( width: 300, height: 300, child: Center( child: Stack( children: <Widget>[ Container( width: 300, height: 300, color: Colors.red, ), //Container Container( width: 250, height: 250, color: Colors.black, ), //Container Container( height: 200, width: 200, color: Colors.purple, ), //Container ], //<Widget>[] ), //Stack ), //Center ), //SizedBox ) //Center ) //Scaffold ) //MaterilApp ); } |
Выход:
Объяснение: Взглянув на код этого приложения flutter, мы видим, что родительский виджет для этого приложения - Scaffold. В верхней части дерева виджетов у нас есть виджет AppBar с заголовком Текстовый виджет, который читается как « GeeksforGeeks », а цвет фона панели приложения - greenAccent [400]. В теле приложения родительским виджетом является Center, за которым следует SizedBox высотой 300 и шириной 300. SizedBox также имеет дочерний элемент Center, который, в свою очередь, содержит виджет Stack. В виджете Stack у нас есть список дочерних виджетов, содержащих три виджета- контейнера. Первый виджет-контейнер имеет высоту и ширину 300, как и SizedBox, и имеет красный цвет. Второй контейнер имеет ширину и высоту 250 и окрашен в черный цвет. Третий Контейнер имеет ширину и высоту 200 и окрашен в пурпурный цвет. Теперь, глядя на приложение, мы видим, что все три контейнера, которые являются дочерними для Stack , сложены друг над другом, причем красные контейнеры находятся внизу, фиолетовые вверху и черные посередине. Все эти три контейнера являются непозиционируемыми виджетами в Stack, поэтому для их свойства alignment установлено значение Alignment.topRight, поэтому мы можем видеть, что все они выровнены по верхнему правому углу.
Пример 2:
Дротик
import 'package:flutter/material.dart' ; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: Text( 'GeeksforGeeks' ), backgroundColor: Colors.greenAccent[400], ), //AppBar body: Center( child: SizedBox( width: 300, height: 300, child: Center( child: Stack( children: <Widget>[ Container( width: 300, height: 300, color: Colors.red, padding: EdgeInsets.all(15.0), alignment: Alignment.topRight, child: Text( 'One' , style: TextStyle(color: Colors.white), ), //Text ), //Container Container( width: 250, height: 250, color: Colors.black, padding: EdgeInsets.all(15.0), alignment: Alignment.bottomLeft, child: Text( 'Two' , style: TextStyle(color: Colors.white), ), //Text ), //Container Container( height: 200, width: 200, padding: EdgeInsets.all(15.0), alignment: Alignment.bottomCenter, decoration: BoxDecoration( image: DecorationImage( image: NetworkImage( ), //DecorationImage ), //BoxDecoration child: Text( "GeeksforGeeks" , style: TextStyle(color: Colors.white, fontSize: 20.0), ), //Text ), //Container ], //<Widget>[] ), //Stack ), //Center ), //SizedBox ) //Center ) //Scaffold ) //MaterialApp ); } |
Выход:
Объяснение: В этом приложении мы добавили отступы, а дочерний виджет Te xt - это каждый из контейнеров с белым цветом текста. В первом контейнере текст - «Один», а выравнивание установлено на Alignment.topRight, что помещает виджет «Текст» в правый верхний угол. Во втором контейнере текст - «Два», а выравнивание установлено на Alignment.bottem left, что помещает дочерний элемент, который является текстом, в нижний левый угол. В третьем контейнере мы добавили фоновое изображение, показывающее логотип GeeksforGeeks , используя свойство украшения в контейнере. Текст в этом контейнере - «GeeksforGeeks», а выравнивание установлено по нижнему центру, что помещает тест над изображением в нижней центральной части контейнера.
Вот как мы можем использовать виджет Stack для отображения текста (или любого другого виджета) поверх другого виджета.
Пример 3:
Дротик
import 'package:flutter/material.dart' ; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: Text( 'GeeksforGeeks' ), backgroundColor: Colors.greenAccent[400], ), //AppBar body: Center( child: SizedBox( width: 300, height: 300, child: Center( child: Stack( fit: StackFit.expand, clipBehavior: Clip.antiAliasWithSaveLayer, overflow: Overflow.visible, children: <Widget>[ Container( width: 300, height: 300, color: Colors.red, ), //Container Positioned( top: 80, left: 80, child: Container( width: 250, height: 250, color: Colors.black, ), ), //Container Positioned( left: 20, top: 20, child: Container( height: 200, width: 200, color: Colors.purple, ), ), //Container ], //<Widget>[] ), //Stack ), //Center ), //SizedBox ) //Center ) //Scaffold ) //MaterilApp ); } |
Выход:
Объяснение: В этом приложении мы обернули фиолетовый и черный Контейнеры позиционированным виджетом, поэтому эти дочерние виджеты теперь позиционируются. В виджете Stack для свойства fit установлено значение S tackFit.expand, что заставит все его дочерние виджеты занять максимальное доступное для них пространство. Для свойства clip установлено значение antiAliasWithSaveLayer, что позволяет избежать размывания краев. И переполнение установлено как видимое, чтобы сделать видимыми выходящие за край части. Теперь, когда мы обернули контейнеры виджетом Positioned, нам нужно указать их положение. Для черного контейнера свойства top и left имеют значение 80 каждое, что приводит к переполнению SizedBox и красного контейнера . Но так как переполнение установлено как видимое, мы можем видеть переполненную часть черного Контейнера. А для фиолетового Контейнера верхнее и левое значение установлено по 20, что немного смещает его по сравнению с первым примером.
Итак, вот как можно использовать виджет Stack. Но мы также можем достичь аналогичного или такого же результата с виджетами CustomSingleChildLayout и CustomMultiChildLayout .