2020/10/31 MDC-102 Flutter: Material Structure and Layout (Flutter)パート3の訳

5. Add a card in a grid

アプリに構造ができてきたので、コンテンツをカードに配置して整理しましょう。

カード(Card)ウィジェットは、一つのコンテントに関する内容とアクションを表示する独立した要素です。 これらは、類似したコンテンツをコレクションとして提示するための柔軟な方法です。

カードの詳細については、マテリアルガイドラインのカードの記事をご覧ください。

カードウィジェットの詳細については、Flutterでのレイアウトの構築をご覧ください。


(1)Add a GridView

上部のアプリバーの下にカードを1枚追加することから始めましょう。 カードウィジェットだけでは、それを表示できる場所に配置するのに十分な情報がないため、GridViewウィジェットにカプセル化する必要があります。

ScaffoldのbodyパラメータのCenterウィジェットをGridViewウィジェットに置き換えます。

body: GridView.count(
  crossAxisCount: 2,
  padding: EdgeInsets.all(16.0),
  childAspectRatio: 8.0 / 9.0,
  // TODO: Build a grid of cards (102)
  children: <Widget>[Card()],
),

コードを読み解きます。 表示するアイテムの数はカウント可能であり、無限ではないため、GridView.count()コンストラクターを呼び出します。 ただし、レイアウトを定義するにはいくつかの情報が必要です。

crossAxisCount:列の数を指定します。今回2列必要なので2と指定します。

FlutterのcrossAxisは、非スクロール軸を意味します。 スクロール方向をmainAxisと呼びます。 したがって、GridViewがデフォルトで示す挙動である垂直スクロールにおいては、crosAxisは水平方向です。

詳細については、ビルディングレイアウトをご覧ください。

padding:フィールドは、GridViewの4つの側面すべてにスペースを提供します。 もちろん、横にGridViewの子がまだないため、末尾または底面のパディングを確認することはできません。

childAspectRatio:フィールドは、アスペクト比(高さに対する幅)に基づいてアイテムのサイズを識別します。

デフォルトでは、GridViewはすべて同じサイズのタイルを作成します。

これをすべて合計すると、GridViewは各子の幅を次のように計算します:([グリッド全体の幅]-[左のパディング]-[右のパディング])/列の数。 次の値を使用します:([グリッド全体の幅] -16-16)/ 2。

高さは、アスペクト比を適用して幅から計算されます::([グリッド全体の幅] -16-16)/ 2 * 9/8。幅から始めて計算しているので、8と9を反転しました。 高さであり、その逆ではありません。

カードは1枚ありますが、空です。 カードに子ウィジェットを追加しましょう。


(2)Layout the contents

カードには、画像、タイトル、およびセカンダリテキスト用の領域が必要です。

GridViewの子を修正します。

children: <Widget>[
  Card(
    clipBehavior: Clip.antiAlias,
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        AspectRatio(
          aspectRatio: 18.0 / 11.0,
          child: Image.asset('assets/diamond.png'),
        ),
        Padding(
          padding: EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text('Title'),
              SizedBox(height: 8.0),
              Text('Secondary Text'),
            ],
          ),
        ),
      ],
    ),
  )
],

このコードは、Cardウィジェットの子ウィジェットを垂直にレイアウトするためにColumnウィジェットを使用します。

crossAxisAlignment:フィールドは、「テキストを前縁に揃える」ことを意味するCrossAxisAlignment.startを指定します。

AspectRatioウィジェットは、提供される画像の種類に関係なく、画像の形状を決定します。

パディングは、テキストを横から少し取り込みます。

2つのテキストウィジェットは垂直に積み重ねられ、その間に8ポイントの空きスペースがあります(SizedBox)。 パディング内にそれら(テキストウィジェット)を収容するために別のColumnを作成します。

プロジェクトを保存します。

このプレビューでは、カードが端からはめ込まれ、角が丸く、影(カードの高さを表す)が表示されています。 全体の形状は、マテリアルでは「コンテナ」と呼ばれます。 (Containerと呼ばれる実際のウィジェットクラスと混同しないでください。)

コンテナを除いて、カード内のすべての要素は実際にはマテリアルではオプションです。 ヘッダーテキスト、サムネイルまたはアバター、小見出しテキスト、仕切り、さらにはボタンやアイコンを追加できます。

カードの内容の詳細については、マテリアルガイドラインのカードの記事を参照してください。

カードは通常、他のカードと一緒にコレクションに表示されます。 それらをコレクションとしてグリッドに配置してみましょう。

ここまでのコード(home.dart)

//home.dart

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  // TODO: Make a collection of cards (102)
  // TODO: Add a variable for Category (104)
  @override
  Widget build(BuildContext context) {
    // TODO: Return an AsymmetricView (104)
    // TODO: Pass Category variable to AsymmetricView (104)
    return Scaffold(
      //↓(1)Add an AppBar widgetで追加。
      appBar:AppBar(
        leading: IconButton(  //←(3)Add a leading IconButtonで追加。
          icon: Icon(
            Icons.menu,
            semanticLabel: 'menu',
          ),
          onPressed: () {
            print('Menu button');
          },
        ),
        title: Text('SHRINE'),  //←(2)Add a Text widgetで追加。
        actions: <Widget>[  //←(4)Add actionsで追加。
          IconButton(
            icon: Icon(
              Icons.search,
              semanticLabel: 'search',
            ),
            onPressed: () {
              print('Search button');
            },
          ),
          IconButton(
            icon: Icon(
              Icons.tune,
              semanticLabel: 'filter',
            ),
            onPressed: () {
              print('Filter button');
            },
          ),
        ],
      ),
      //↓(1)Add a GridViewで追加。
      body: GridView.count(
        crossAxisCount: 2,
        padding: EdgeInsets.all(10.0),
        childAspectRatio: 8.0 / 9.0,
        // TODO: Build a grid of cards (102)
        children: <Widget>[
          //↓(2)Layout the contentsで追加。
          Card(
            clipBehavior: Clip.antiAlias,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                AspectRatio(
                  aspectRatio: 18.0 / 11.0,
                  child: Image.asset('assets/diamond.png'),
                ),
                Padding(
                  padding: EdgeInsets.fromLTRB(22.0,20.0, 16.0, 2.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text('Title'),
                      SizedBox(height: 8.0),
                      Text('Secondary Text'),
                    ],
                  ),
                ),
              ],
            ),
          )
        ],
      ),
      //↓(3)popで追加。
      resizeToAvoidBottomInset: false,
    );
  }
}

次のページ(パート4)へ>>

参考

https://codelabs.developers.google.com/codelabs/mdc-102-flutter#4

コメントを残す

メールアドレスが公開されることはありません。