[플러터] 텍스트 파일 여러개에서 제목만 읽어 추출하는 방법

Posted on

플러터에서 글로 된 자료를 저장하고 불러오는 방법을 생각해보았습니다. 대략 생각해본대로 한 것은 우선 이런 방법이었습니다.

assets/docs/idols.info0.md
assets/docs/idols.info1.md
...
assets/docs/idols.infon.md

이런 구조의 디렉토리에서 파일을 읽어와서 표시하는 구조입니다. 파일명을 일일히 입력하지 않으려고 고안했던 방법은

retrieveGridViewData() async {
  for (int i = 0; i < 3; i++) {
    text = await File('assets/docs/idols.info$i.md').readAsString();
    files.add(text);
  }
}

였는데요. 이게 잘 작동을 안해서 궁리를 조금 했습니다. 고안한 코드는

List entities = [
    'assets/docs/idols.info0.md',
    'assets/docs/idols.info1.md',
    'assets/docs/idols.info2.md'
];

Future<List<String>> retrieveGridViewData() async {
    List<String> contents = <String>[];
    List<String> title = <String>[];
    RegExp regex = RegExp(r'(#{2}\s)(.*)');
    for (final entity in entities) {
        contents.add(await rootBundle.loadString(entity));
    }
    for (int i = 0; i < contents.length; i++) {
        RegExpMatch? match = regex.firstMatch(contents.elementAt(i));
        String temp = match!.group(0).toString();
        temp = temp.split('##').last;
        title.add(temp);
    }
    return title;
}

처럼 파일명과 디렉토리를 entities 리스트에 저장해서 처리하는 방법입니다. 우선 첫번째 루프

for (final entity in entities) {
    contents.add(await rootBundle.loadString(entity));
}

이 코드가 파일을 읽어옵니다.

for (int i = 0; i < contents.length; i++)  {
    RegExpMatch? match = regex.firstMatch(contents.elementAt(i));
    String temp = match!.group(0).toString();
    temp = temp.split('##').last;
    title.add(temp);
}
return title;

그리고 이 코드가 ## 로 지정된 제목을 읽어와서 정규식으로 검사하고 자릅니다.

이 title 리스트를 FutureBuilder로 감싼 GridView에 넘겨서 snapshot.requiredData.elementAt(index) 로 받으면 제목만 표시합니다.

@override
Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
            title: const Text(
                '아이돌의 황혼기 - 글 목록',
            ),
        ),
        body: FutureBuilder<List<String>>(
           future: retrieveGridViewData(),
           builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
                 return GridView.builder(
                gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                maxCrossAxisExtent: 200,
                crossAxisSpacing: 20,
                mainAxisSpacing: 20),
                itemCount: 3,
                itemBuilder: (BuildContext context, int index) {
                    return Container(
                        padding: const EdgeInsets.all(20.0),
                            child: Text(
                                style: TextStyle(
                                fontSize: 20.0,
                            ),
                            snapshot.requireData.elementAt(index),
                        ),
                    );
                },
          );
      },
  ),);
}

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다