Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutterでライセンスページを独自に作る際のハマりポイント

そた
March 27, 2024
450

 Flutterでライセンスページを独自に作る際のハマりポイント

LicenseEntryの扱い方について

そた

March 27, 2024
Tweet

Transcript

  1. 全然違った abstract class LicenseEntry { Iterable<String> get packages; Iterable<LicenseParagraph> get

    paragraphs; } なぜ抽象クラス...? どうしてpackagesがIterableなんだ? LicenseParagraphってなんぞや? この謎のクラスが配列で返ってくるとかどうすればいいんだ...? 11
  2. 13

  3. パッケージにライセンスが紐づく形に変換してあげる Future<Map<String, List<String>>> getLicenseInfo() async { final licenseEntries = await

    LicenseRegistry.licenses.toList(); Map<String, List<String>> licenseInfo = {}; for (var entry in licenseEntries) { final entryWithLineBreaks = entry as LicenseEntryWithLineBreaks; for (var element in entryWithLineBreaks.packages) { if (licenseInfo.containsKey(element)) { licenseInfo[element]!.add(entryWithLineBreaks.text); } else { licenseInfo[element] = [entryWithLineBreaks.text]; } } } 15
  4. FutureBuilder( future: getLicenseInfo(), builder: (context, AsyncSnapshot<Map<String, List<String>>> snapshot) { if

    (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { final key = snapshot.data!.keys.elementAt(index); final value = snapshot.data![key]!; return ExpansionTile( title: Text('$key ${value.length} 件'), children: [ for (var license in value) ListTile( title: Text(license), ), ], ); }, ); }), 16
  5. class LicenseParagraph { const LicenseParagraph(this.text, this.indent); /// 先頭、末尾の空白を除いた段落のテキスト final String

    text; /// 段落のインデントのステップ数。 /// /// * 0 は段落がインデントされていないことを意味します。 /// * 1 は段落が1 単位のインデントがあることを意味します。 /// * 2 は段落が2 単位のインデントがあることを意味します。 /// /// ... などです。 /// /// さらに、特別な値[centeredIndent] は、段落がインデントされるのではなく、 /// 中央に配置されることを示すために使用できます。 final int indent; 19
  6. Future<Map<String, List<List<LicenseParagraph>>>> getLicenseInfo() async { final licenseEntries = await LicenseRegistry.licenses.toList();

    Map<String, List<List<LicenseParagraph>>> licenseInfo = {}; for (var entry in licenseEntries) { for (var element in entry.packages) { if (licenseInfo.containsKey(element)) { licenseInfo[element]!.add(entry.paragraphs.toList()); } else { licenseInfo[element] = [entry.paragraphs.toList()]; } } } } 22
  7. ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { final key =

    snapshot.data!.keys.elementAt(index); final value = snapshot.data![key]!; return ExpansionTile( title: Text('$key ${value.length} 件'), children: [ for (var license in value) Column( children: [ for (var paragraph in license) Padding( padding: EdgeInsets.only( left: 16.0 * paragraph.indent), child: ListTile( title: Text(paragraph.text), ), ), ], ), ], ); }, ); 23