IntrinsicHeightを使って動的にRow内の子のサイズを揃える

こんにちは、株式会社Pentagonでアプリ開発をしている石渡港です。
https://pentagon.tokyo
今日は、IntrinsicHeightを使って動的にRow内の子のサイズを揃える方法について簡単にまとめたいと思います。

目次

■ 経緯

簡単な表を作って表示したかったが、片側の背景色がきれいに表示されないことがあった、例えばこんな感じです。

https://assets.st-note.com/production/uploads/images/55393936/picture_pc_87a83842e689efd1c6aa61fd5a166737.png?width=800

import 'package:flutter/material.dart';

void main() {
 runApp(MyApp());
}

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Flutter Demo',
     theme: ThemeData(
       primarySwatch: Colors.blue,
       visualDensity: VisualDensity.adaptivePlatformDensity,
     ),
     home: Scaffold(
       body: ListView(
         children: [
           _createDivider(),
           _createCell('test'),
           _createDivider(),
           _createCell('例えば\nこんな\n感じに\n高さが違う場合'),
           _createDivider(),
         ],
       ),
     ),
   );
 }

 Widget _createDivider() {
   return const Divider(
     height: 1,
     color: Colors.grey,
   );
 }

 Widget _createCell(String string) {
   return Row(
     children: [
       Container(
         width: 120,
         color: Colors.lightGreenAccent,
         alignment: Alignment.centerLeft,
         padding: const EdgeInsets.all(16.0),
         child: Text(
           'タイトル',
           style: const TextStyle(color: Colors.black, fontSize: 14),
         ),
       ),
       Container(
         padding: const EdgeInsets.all(16.0),
         child: Flexible(
           child: Text(
             string,
             textAlign: TextAlign.left,
             style: const TextStyle(color: Colors.black, fontSize: 14),
           ),
         ),
       ),
     ],
   );
 }
}

■ 改善方法

上記のコードだと、Row自体の高さが、右側の要素の高さにはなっているが、タイトル側のContainerの高さが適切な高さになっていない。そのため、RowをIntrinsicHeightで包んであげて、RowのcrossAxisAlignmentをCrossAxisAlignment.stretchにしてあげることで、適切な高さに変わります。

https://assets.st-note.com/production/uploads/images/55394294/picture_pc_e20ea823515dbb82282889b834fe379a.png?width=800

import 'package:flutter/material.dart';

void main() {
 runApp(MyApp());
}

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Flutter Demo',
     theme: ThemeData(
       primarySwatch: Colors.blue,
       visualDensity: VisualDensity.adaptivePlatformDensity,
     ),
     home: Scaffold(
       body: ListView(
         children: [
           _createDivider(),
           _createCell('test'),
           _createDivider(),
           _createCell('例えば\nこんな\n感じに\n高さが違う場合'),
           _createDivider(),
         ],
       ),
     ),
   );
 }

 Widget _createDivider() {
   return const Divider(
     height: 1,
     color: Colors.grey,
   );
 }

 Widget _createCell(String string) {
   return IntrinsicHeight(
     child: Row(
       crossAxisAlignment: CrossAxisAlignment.stretch,
       children: [
         Container(
           width: 120,
           color: Colors.lightGreenAccent,
           alignment: Alignment.centerLeft,
           padding: const EdgeInsets.all(16.0),
           child: Text(
             'タイトル',
             style: const TextStyle(color: Colors.black, fontSize: 14),
           ),
         ),
         Container(
           padding: const EdgeInsets.all(16.0),
           child: Flexible(
             child: Text(
               string,
               textAlign: TextAlign.left,
               style: const TextStyle(color: Colors.black, fontSize: 14),
             ),
           ),
         ),
       ],
     ),
   );
 }
}

以上です🙋

採用情報はこちら
目次