개발하는 두더지

Flutter - CardView 구현하기 본문

Flutter

Flutter - CardView 구현하기

덜지 2019. 5. 8. 01:10

카드는 하나의 주제에 대해서 정보를 표시하는데 유용하게 사용됩니다.

Flutter에서 독립적으로 사용하기엔 정보가 충분하지 않아서 GridView 와 같은 위젯에 감싸서 사용해야 합니다.

body: GridView.count(
  crossAxisCount: 2,
  padding: EdgeInsets.all(16.0),
  childAspectRatio: 8.0 / 9.0,

  children: <Widget>[Card()],
),

위의 코드를 실행시켜보면 비어있는 카드 한장을 구현할 수 있습니다.
GridView는 아이템 항목 개수만큼 count 메서드를 invoke (호출) 합니다.


crossAxisCount 는 행에 몇개의 아이템을 보여줄지를 결정합니다. 예제에서는 2개를 보여주도록 설정합니다.
cross axis 는 스크롤의 방향을 지정하지 않습니다. main axis 가 세로로 스크롤할지, 가로로 스크롤할지를 결정해줍니다.
childAspectRatio 는 너비/넓이에 따라 항목의 크기를 결정해줍니다.

 

이제 아이템 항목을 꾸며봅시다.

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

import 'model/products_repository.dart';
import 'model/product.dart';

class HomePage extends StatelessWidget {

  List<Card> _buildGridCards(BuildContext context) {
    List<Product> products = ProductsRepository.loadProducts(Category.all);

    if (products == null || products.isEmpty) {
      return const <Card>[];
    }

    final ThemeData theme = Theme.of(context);
    final NumberFormat formatter = NumberFormat.simpleCurrency(
        locale: Localizations.localeOf(context).toString());

    return products.map((product) {
      return Card(
        clipBehavior: Clip.antiAlias,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            AspectRatio(
              aspectRatio: 18 / 11,
              child: Image.asset(
                product.assetName,
                package: product.assetPackage,
                fit: BoxFit.fitWidth,
              ),
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      product.name,
                      style: theme.textTheme.title,
                      maxLines: 1,
                    ),
                    SizedBox(height: 8.0),
                    Text(
                      formatter.format(product.price),
                      style: theme.textTheme.body2,
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      );
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(
            Icons.menu,
            semanticLabel: 'menu',
          ),
          onPressed: () {
            print('Menu button');
          },
        ),

        title: Text('SHRINE'),

        actions: <Widget>[
          IconButton(
            icon: Icon(
              Icons.search,
              semanticLabel: 'search',
            ),
            onPressed: () {
              print('Search button');
            },
          ),
          IconButton(
            icon: Icon(
              Icons.tune,
              semanticLabel: 'filter',
            ),
            onPressed: () {
              print('Filter button');
            },
          ),
        ],
      ),
      body: GridView.count(
        crossAxisCount: 2,
        padding: EdgeInsets.all(16.0),
        childAspectRatio: 8.0 / 9.0,

        children: _buildGridCards(context),
      ),
      resizeToAvoidBottomInset: false,
    );
  }
}
Comments