Chuyển đến nội dung chính

Bài 4: Layouts & Responsive Design

Row, Column, Stack, Expanded, Flexible. Container, Padding, SizedBox. ListView, GridView, CustomScrollView, Slivers. MediaQuery, LayoutBuilder, responsive breakpoints.

💻 Lập trình — Bài 4 Bài 4: Layouts & Responsive Design

Flutter & Dart: Từ Cơ bản đến Nâng cao

Phần 1: Dart & Flutter Fundamentals

xdev.asia

1. Row & Column

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Expanded(flex: 2, child: Text('Left')),
    Expanded(flex: 1, child: Text('Right')),
  ],
);

Column(
  children: [
    Flexible(child: Container(color: Colors.red)),
    Flexible(child: Container(color: Colors.blue)),
  ],
);

2. Stack & Positioned

Stack(
  children: [
    Image.network(imageUrl, fit: BoxFit.cover),
    Positioned(
      bottom: 16,
      left: 16,
      child: Text('Overlay', style: TextStyle(color: Colors.white, fontSize: 24)),
    ),
  ],
);

3. ListView & GridView

// ListView.builder — lazy loading
ListView.builder(
  itemCount: products.length,
  itemBuilder: (context, index) {
    final product = products[index];
    return ListTile(
      title: Text(product.name),
      subtitle: Text('${product.price}đ'),
    );
  },
);

// GridView
GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    mainAxisSpacing: 8,
    crossAxisSpacing: 8,
    childAspectRatio: 0.75,
  ),
  itemCount: products.length,
  itemBuilder: (context, index) => ProductCard(product: products[index]),
);

4. CustomScrollView & Slivers

CustomScrollView(
  slivers: [
    SliverAppBar(
      expandedHeight: 200,
      floating: true,
      pinned: true,
      flexibleSpace: FlexibleSpaceBar(title: Text('Products')),
    ),
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('Item $index')),
        childCount: 50,
      ),
    ),
  ],
);

5. Responsive Design

LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth > 900) {
      return DesktopLayout();
    } else if (constraints.maxWidth > 600) {
      return TabletLayout();
    }
    return MobileLayout();
  },
);

// MediaQuery
final screenWidth = MediaQuery.of(context).size.width;
final isTablet = screenWidth >= 600;

Bài tiếp theo: Navigation & Routing.