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 heightwidth

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:, RadialGradientvà 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 BoxDecorationvà bất cứ thứ gì BoxDecorationở trên cùng.

Với backgroundBlendModebạn có thể sử dụng một danh sách dài các thuật toán được chỉ định trong BlendModeenum.

Đầ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ụ

Đủ không gian theo chiều dọc
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!

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.