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

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

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for そた そた
March 27, 2024
1.5k

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

LicenseEntryの扱い方について

Avatar for そた

そた

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