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

第 4 課:佈局與響應式設計

行、列、堆疊、擴充、靈活。容器、填充物、SizedBox。 ListView、GridView、CustomScrollView、Slivers。 MediaQuery、LayoutBuilder、響應式斷點。

💻 程式設計 — 第 4 課 第 4 課:佈局與響應式設計

Flutter 和 Dart:從基礎到高級

第 1 部分:Dart 和 Flutter 基礎知識

亞洲開發網

1. 列和行

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(
  children: [
    Image.network(imageUrl, fit: BoxFit.cover),
    Positioned(
      bottom: 16,
      left: 16,
      child: Text('Overlay', style: TextStyle(color: Colors.white, fontSize: 24)),
    ),
  ],
);

3. 清單視圖和網格視圖

// 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.響應式設計

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;

下一篇: 導航和路線選擇。