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

レッスン 4: レイアウトとレスポンシブ デザイン

行、列、スタック、展開、柔軟。コンテナー、パディング、SizedBox。 ListView、GridView、CustomScrollView、Sliver。 MediaQuery、LayoutBuilder、レスポンシブ ブレークポイント。

💻 プログラミング — レッスン 4 レッスン 4: レイアウトとレスポンシブ デザイン

フラッター&ダーツ: 基本から上級まで

パート 1: ダーツとフラッターの基礎

xdev.asia

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 とスライバー

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;

次の記事: ナビゲーションとルーティング。