折り畳み可能なパネル ExpansionPanel のリストを扱う方法

ここでは ExpansionPanel と ExpansionPanelList の使い方を紹介します。

ExpansionPanel は Card に似ていますが、ヘッダーをタップすることで、コンテンツのボディ部分を折りたたんだり、展開したりすることができます。

Card の使い方については「ListView で Card を使う方法」をみてください。

ここではパネルのコンテンツを写真として、ヘッダー部分をタップすることによって写真が見えるようになったり、内容が折りたたまれてヘッダー部分がみえるようにしたりします。

ここではビーチやレストランを表示する画面になっていて、そうした場所の情報は PlaceItem というクラスを作り保持しています。

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

void main() {
  debugPaintSizeEnabled = false;
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyApp(),
    ),
  );
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _State();
  }
}

class PlaceItem {
  bool isExpanded;
  String name;
  String image;

  PlaceItem(this.isExpanded, this.name, this.image);
}

ExpansionPanel _createPanel(PlaceItem place) {
  return ExpansionPanel(
    headerBuilder: (BuildContext context, bool isExpanded) {
      return Container(
        padding: EdgeInsets.all(8.0),
        child: Row(
          children: <Widget>[
            Padding(
              padding: EdgeInsets.only(right: 10.0),
              child: Icon(Icons.image),
            ),
            Text(
              place.name,
              style: TextStyle(
                fontSize: 16,
                fontWeight: FontWeight.bold,
              ),
            )
          ],
        ),
      );
    },
    body: Image.asset('assets/' + place.image),
    isExpanded: place.isExpanded,
  );
}

class _State extends State<MyApp> {
  var _placeList = new List<PlaceItem>();

  @override
  void initState() {
    _placeList.add(
      PlaceItem(false, 'Huntington Beach', 'huntington-beach.jpg'),
    );
    _placeList.add(
      PlaceItem(false, 'The Hat', 'the-hat.jpg'),
    );
    _placeList.add(
      PlaceItem(false, 'Shake Shack', 'shake-shack.jpg'),
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('California'),
      ),
      body: Container(
        padding: EdgeInsets.all(8.0),
        child: ListView(
          children: <Widget>[
            ExpansionPanelList(
              expansionCallback: (int index, bool isExpanded) {
                setState(() {
                  _placeList[index].isExpanded = !_placeList[index].isExpanded;
                });
              },
              children: _placeList.map(_createPanel).toList(),
            )
          ],
        ),
      ),
    );
  }
}

ExpansionPanel を返す _createPanel という関数を作ります。 PlaceItem のリストに対して map 関数を使ってそれぞれの要素に対して _createPanel 関数を呼ぶことで、ExpansionPanel のリストを取得しています。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Flutter 入門