Flutterを使用したUI開発

こんにちは、Habr! 記事「 Building Layouts 」の翻訳に注目してください。



今日は以下を見つけます。





今日のレッスンの結果は、次の画面レイアウトになります



画像








ステップ0:プロジェクトのセットアップ



最初に、新しいプロジェクトを作成しますFile-> New Flutter Project-> next、next、next ...

次に、プロジェクトのルートに画像ディレクトリを作成し、そこにlake.jpgという名前のファイルを配置します。ここからファイルをダウンロードできます- リンク



また、構成ファイルpubspec.yaml(iOSのAndroidやココアポッドのgradleなど、外部依存関係を追加できます)を修正する必要もあります。 ファイル自体のテキストはここからダウンロードできます。



プロジェクトソースはここからダウンロードできます-main.dartファイルに配置する必要があります



ステップ1:スクリーンチャート



最初に、レイアウトを単純な要素に分割します





まず、主要な大きな要素を特定します。 この例では、4つの要素が列に配置されています。1つの写真、2つの行、1つのテストブロックです。



画像



次に、各行を分析します。 「タイトル」と呼ばれる最初の行には、テキストの列、星のアイコン、および数字の3つの子があります。 最初の列には2行が含まれています。 最初の列は多くのスペースを占有するため、拡張可能なウィジェットでラップする必要があります。



画像



ボタンセクションと呼ばれる次の行にも3つの子があります。 それぞれに画像とテキストが含まれています。



画像



最後に、レイアウトを単純な要素にレイアウトしました。 ディスプレイのレイアウトに「ボトムアップ」アプローチを使用する最も簡単な方法。 複雑な構造を避けるために、UIを変数と関数に分割します。



ステップ2:ヘッダーの行を作成する



最初に、ヘッダーセクションの左列を作成する必要があります。 拡張可能なウィジェット内に列を挿入すると、列が展開され、行内の残りのスペースがすべて使用されます。 crossAxisAlignmentプロパティをCrossAxisAlignment.startに設定して、列を行の先頭に揃えます。



コンテナ内にテキスト行を配置すると、パディングを有効にできます。 列の2番目の子もテキストであり、グレーアウトされています。 最後の2つの要素には、赤色の「星」アイコンと「41」の値のテキストが付いています。 行全体をコンテナに入れ、各辺に32ピクセルのインデントを追加します。 これらの手順を完了するためのコードを以下に示します。



class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { Widget titleSection = Container( padding: const EdgeInsets.all(32.0), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.only(bottom: 8.0), child: Text( 'Oeschinen Lake Campground', style: TextStyle( fontWeight: FontWeight.bold, ), ), ), Text( 'Kandersteg, Switzerland', style: TextStyle( color: Colors.grey[500], ), ), ], ), ), Icon( Icons.star, color: Colors.red[500], ), Text('41'), ], ), ); //... }
      
      





ステップ3:一連のボタンを作成する



ボタンセクションは3つの列で構成され、同様の原則に従って作成されます-テキスト行の上のアイコン。 この行の列は均等に塗りつぶされ、テキストとアイコンはメインの色で描画されます。この色は、build()メソッドのプロジェクトで青として選択されています。



 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), //... }
      
      





各行の構築コードはほぼ同一であるため、アイコンとテキストを含み、このウィジェットで列を返すbuildButtonColumn()などのネストされた関数を使用するのが最も効率的です。



 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Column buildButtonColumn(IconData icon, String label) { Color color = Theme.of(context).primaryColor; return Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: color), Container( margin: const EdgeInsets.only(top: 8.0), child: Text( label, style: TextStyle( fontSize: 12.0, fontWeight: FontWeight.w400, color: color, ), ), ), ], ); } //... }
      
      





ビルド関数は、アイコンを列に直接追加します。 コンテナにテキストを配置してパディングを追加し、アイコンから分離します。 関数を呼び出し、列内にアイコンとテキストを渡すことにより、これらの列の各行を作成します。 MainAxisAlignment.spaceEvenを使用してメイン軸に沿って列を配置し、各列の前、間、後に空きスペースを整理します。



 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Widget buttonSection = Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ buildButtonColumn(Icons.call, 'CALL'), buildButtonColumn(Icons.near_me, 'ROUTE'), buildButtonColumn(Icons.share, 'SHARE'), ], ), ); //... }
      
      





ステップ4:説明セクションを作成する



非常に長い説明セクションを定義します。 コンテナにテキストを配置し、各エッジから32ピクセルのインデントを追加します。



 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Widget textSection = Container( padding: const EdgeInsets.all(32.0), child: Text( ''' Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese Alps. Situated 1,578 meters above sea level, it is one of the larger Alpine Lakes. A gondola ride from Kandersteg, followed by a half-hour walk through pastures and pine forest, leads you to the lake, which warms to 20 degrees Celsius in the summer. Activities enjoyed here include rowing, and riding the summer toboggan run. ''', softWrap: true, ), ); //... }
      
      





ステップ5:イメージセクションを作成する



4列のうち3列は既に構築されており、画像列を作成するためだけに残っています。 このプロジェクトで使用される画像は、Creative Commonsライセンスの下でオンラインで入手できます。 しかし、それは大きく、ゆっくりロードされます。 ステップ0で、プロジェクトに画像を追加し、構成ファイルを更新しました。次に、コードにリンクを追加します。



 return MaterialApp( //... body: ListView( children: [ Image.asset( 'images/lake.jpg', height: 240.0, fit: BoxFit.cover, ), // ... ], ), //... );
      
      





BoxFit.coverは、Flutterフレームワークに、画像はできるだけ小さくする必要がありますが、レンダリング領域全体をカバーするように指示します。



ステップ6:すべてをまとめる



最後のステップでは、コードのすべての部分をまとめて収集します。 ウィジェットは、小さなデバイスでスクロールしているときにListViewが自動的にスクロールするため、ColumnではなくListViewで編成されます。



 //... return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: Text('Top Lakes'), ), body: ListView( children: [ Image.asset( 'images/lake.jpg', width: 600.0, height: 240.0, fit: BoxFit.cover, ), titleSection, buttonSection, textSection, ], ), ), ); //...
      
      






All Articles