Container
Một trong những Widget được sử dụng nhiều nhất – và vì những lý do này:
Container as a layout tool
Khi bạn không chỉ định height
và width
của Container
, nó sẽ khớp với child
kích thước của nó
Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Container as a layout')), body: Container( color: Colors.yellowAccent, child: Text("Hi"), ), ); }
Nếu bạn muốn kéo dài Container
để khớp với cha của nó, hãy sử dụng double.infinity
cho các thuộc tính height
và width
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 as decoration
Bạn có thể sử dụng thuộc tính color để làm thay đổi màu nền của Container
bằng decoration
và foregroundDecoration
.
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"), ), ); }
. . .
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"), ), ); }
Container as Transform
Nếu bạn không muốn sử dụng widget Transform
để thay đổi bố cục của mình, bạn có thể sử dụng transform
thuộc tính từ Container
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
BoxDecoration thường được sử dụng trên tiện ích Container để thay đổi diện mạo của Container.
image: DecorationImage
Đặt một hình ảnh làm nền:
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', ), ), ), ), ), );
border: Border
Chỉ định đường viền của Container sẽ trông như thế nào.
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
Cho phép làm tròn các góc của đường viền.
<em>borderRadius</em>
không hoạt động nếu <em>shape</em>
trong decoration là <em>BoxShape.circle</em>
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)), ), ), ), );
shape: BoxShape
BoxDecoration có thể là hình chữ nhật / hình vuông hoặc hình elip / hình tròn.
Đối với bất kỳ hình dạng nào khác, bạn có thể sử dụng <em>ShapeDecoration</em>
thay thế cho <em>BoxDecoration</em>
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>
Thêm bóng vào Container .
Tham số này là một danh sách vì bạn có thể chỉ định nhiều bóng khác nhau và hợp nhất chúng lại với nhau.
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), ], ), ), ), );
gradient
Có ba loại gradient LinearGradient
:, RadialGradient
và SweepGradient
.
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, ], ), ), ), ), );
. . .
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], ), ), ), ), );
. . .
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
là tài sản phức tạp nhất của BoxDecoration
.
Nó chịu trách nhiệm trộn các màu / độ chuyển màu với nhau BoxDecoration
và bất cứ thứ gì BoxDecoration
ở trên cùng.
Với backgroundBlendMode
bạn có thể sử dụng một danh sách dài các thuật toán được chỉ định trong BlendMode
enum.
Đầu tiên, hãy đặt BoxDecoration
là foregroundDecoration
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', ), ), ), );
. . .
Material
Đường viền với các góc cắt
Scaffold( appBar: AppBar(title: Text('shape: BeveledRectangleBorder')), body: Center( child: Material( shape: const BeveledRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(20)), side: BorderSide(color: Colors.black, width: 4), ), color: Colors.yellow, child: Container( height: 200, width: 200, ), ), ), );
. . .
Slivers
SliverFillRemaining
Widget này không thể thay thế khi bạn muốn căn giữa nội dung của mình ngay cả khi không có đủ dung lượng cho nó. Ví dụ
Scaffold( appBar: AppBar(title: Text('SliverFillRemaining')), body: CustomScrollView( slivers: [ SliverFillRemaining( hasScrollBody: false, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: const [ FlutterLogo(size: 200), Text( 'This is some longest text that should be centered' 'together with the logo', textAlign: TextAlign.center, ), ], ), ), ], ), );
Trong trường hợp không có đủ không gian cho nội dung được căn giữa, nội dung SliverFillRemaining
sẽ có thể cuộn được:
Nếu không có SliverFillRemaining
nội dung sẽ tràn như thế này:
Làm đầy không gian còn lại
Ngoài việc hữu ích cho việc căn giữa nội dung của bạn, SliverFillRemaining
nó sẽ lấp đầy không gian trống còn lại của khung nhìn. Để làm được điều đó, widget này phải được đặt vào CustomScrollView
và cần phải là mảnh cuối cùng
Trong trường hợp không có đủ dung lượng, tiện ích con sẽ có thể cuộn được:
Scaffold( appBar: AppBar(title: Text('SliverFillRemaining')), body: CustomScrollView( slivers: [ SliverList( delegate: SliverChildListDelegate(const [ ListTile(title: Text('First item')), ListTile(title: Text('Second item')), ListTile(title: Text('Third item')), ListTile(title: Text('Fourth item')), ]), ), SliverFillRemaining( hasScrollBody: false, child: Container( color: Colors.yellowAccent, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: const [ FlutterLogo(size: 200), Text( 'This is some longest text that should be centered' 'together with the logo', textAlign: TextAlign.center, ), ], ), ), ), ], ), );
. . .
SizedBox
Đây là một trong những Widget đơn giản nhưng hữu ích nhất
SizedBox dưới dạng ConstrainedBox
SizedBox
có thể hoạt động theo cách tương tự như ConstrainedBox
SizedBox.expand( child: Card( child: Text('Hello World!'), color: Colors.yellowAccent, ), ),
. . .
SizedBox dưới dạng padding
Khi cần thêm phần đệm hoặc lề, bạn có thể chọn Padding
hoặc Container
các widget. Nhưng chúng có thể dài dòng hơn và khó đọc hơn so với việc thêm một Sizedbox
Column( children: <Widget>[ Icon(Icons.star, size: 50), const SizedBox(height: 100), Icon(Icons.star, size: 50), Icon(Icons.star, size: 50), ], ),
SizedBox như một đối tượng vô hình
Nhiều khi bạn muốn ẩn / hiện một tiện ích phụ thuộc vào bool
Widget build(BuildContext context) { bool isVisible = ... return Scaffold( appBar: AppBar( title: Text('isVisible = $isVisible'), ), body: isVisible ? Icon(Icons.star, size: 150) : const SizedBox(), ); }
Vì SizedBox
có một hàm const
tạo nên việc sử dụng const SizedBox()
thực sự rất tối ưu**.
** Một giải pháp tối ưu hơn sẽ là sử dụng Opacity
widget và thay đổi opacity
giá trị thành 0.0
. Hạn chế của giải pháp này là tiện ích đã cho sẽ chỉ ẩn, vẫn chiếm không gian.
. . .
Trên các nền tảng khác nhau, có những khu vực đặc biệt như Thanh trạng thái trên Android hoặc Notch trên iPhone X mà chúng tôi có thể tránh vẽ dưới.
Giải pháp cho vấn đề này là SafeArea
widget (ví dụ không có / có SafeArea
)
Widget build(BuildContext context) { return Material( color: Colors.blue, child: SafeArea( child: SizedBox.expand( child: Card(color: Colors.yellowAccent), ), ), ); }
Kết thúc phần 3!