인프런 커뮤니티 질문&답변

yonglimlee님의 프로필 이미지
yonglimlee

작성한 질문수

Flutter 입문 - 안드로이드, iOS 개발을 한 번에 (with Firebase)

GridView에 데이터가 표시가 안됩니다.

작성

·

180

0

안녕하세요.

인스타그램 클론 강의 듣고, 혼자 토이플젝을 하나 하고 있는데 GridView에 데이터가 표시되지 않아 질문드립니다.

 

 

기능

#가치 라는 해시태그 버튼을 클릭하면 단어들중 #가치 라는 카테고리에 속하는 단어를 하단에 출력

 

#구현 사항

  • 단어를 여러 카테고리에 속하게 나누어 파이어베이스에 등록 완료

  • 해시태그 버튼 클릭했을때, 해당하는 단어들 list로 가지고 옴.

#문제사항

  • 단어들을 list로 가지고와서 GridView에 출력하게 했으나 출력되지 않음.

 

첫번째 이미지는 더미데이터를 집어놓은거구요.

두번째 이미지가 현재 상황입니다.

 

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:uddutsi/tab/home/home_model.dart';
import 'package:uddutsi/tab/search/search_model.dart';

import '../../model/category.dart';
import '../../model/word.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  final dics = const [
    '단어1', '차갑다', '버르장머리없다','거지같다','착하다',
    '단어1', '차갑다', '버르장머리없다','거지같다','착하다',
    '단어1', '차갑다', '버르장머리없다','거지같다','착하다',
    '단어1', '차갑다', '버르장머리없다','거지같다','착하다',
  ];

  @override
  Widget build(BuildContext context) {

    final model = HomeModel();
    final searchModel = SearchModel();

    List<Word> wordList = [];

    return Scaffold(
      appBar: AppBar(
        title: const Text('[test]'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            const SizedBox(height: 10),
            StreamBuilder<QuerySnapshot<Category>>(
              stream: model.categoriesStream,
              builder: (context, snapshot) {

                if (snapshot.hasError) {
                  return const Text('Something went wrong');
                }

                if (snapshot.connectionState == ConnectionState.waiting) {
                  return const Center(child: CircularProgressIndicator());
                }

                List<Category> categories = snapshot.data!.docs.map((e) => e.data()).toList();

                return Wrap(
                  direction: Axis.horizontal, //나열 방향
                  alignment: WrapAlignment.start, //정렬방식
                  spacing: 5, //좌우간격
                  runSpacing: 5, //상하간격
                  children: <InkWell>[
                    for(var i = 0; i<categories.length; ++i)
                      ...[
                        InkWell(
                          child: Container(
                            padding: const EdgeInsets.all(6),
                            decoration: BoxDecoration(
                              color: const Color(0xffdddddd),
                              borderRadius: BorderRadius.circular(6),
                            ),
                            child: Text('#${categories[i].name}'),
                          ),
                          onTap: () async{
                            print('click ${categories[i].name}');
                            List<dynamic> _listData = await searchModel.getWordsByCategoryId(categories[i].id);

                            setState(() {
                              wordList.clear();
                              wordList = _listData.map((dynamic item) => Word.fromJson(item)).toList();
                              wordList.forEach((element) {print('${element.name}');});
                            });

                          },
                        ),
                      ],
                  ],
                );
              }
            ),
            const SizedBox(height: 10),
            Expanded(
              child: GridView.builder(
                itemCount: wordList.length,
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3, //3열을 만드는 속성
                  crossAxisSpacing: 2.0,
                  mainAxisSpacing: 2.0,
                ),
                itemBuilder: (BuildContext context, int index){
                  final dic = wordList[index];
                  return GestureDetector(
                    onTap: (){
                      print('click ${dic.name}');
                    },
                    child: Hero(
                      tag: dic,
                      child: Text(dic.name),
                    )
                  );
                },

              ),
            ),
          ],
        ),
      ),
    );
  }
}

setState 함수안에 데이터를 업데이트 한후, 출력을 해보면 wordList가 잘 출력되는것까지는 확인했는데 GridView에서는 출력이 안됩니다.

혹시 GridView가 아닌 다른 위젯으로 출력을 해야할까요? 검색을 하려해도 무슨 키워드로 검색을 해야할지 감이 안 잡혀서요. 답변 기다리겠습니다. ^^

답변 1

0

오준석님의 프로필 이미지
오준석
지식공유자

wordList 선언을 build() 메서드 밖에서 하셔야 될 것 같습니다.

화면이 재생성 되면서 build() 안에서 계속 빈 리스트로 초기화되고 있습니다.

참고로 본 강의에서는 다음강의와의 연계를 생각해서 비슷한 코드로 만들기 위해 일부러 build() 안에 모델 코드를 작성하지만

사실은 build() 밖에 두는게 좋습니다. 따라서 다음 세 코드를 필드로 옮기는게 좋습니다.

final model = HomeModel();
final searchModel = SearchModel();
List<Word> wordList = [];

yonglimlee님의 프로필 이미지
yonglimlee
질문자

헛 바로 해결되었네요!! ㅎㅎ 감사합니다.

setState()를 하게 되면 build(){} 안에 화면을 다시 그린다고 보면되는걸까요?

오준석님의 프로필 이미지
오준석
지식공유자

네. 맞습니다.

토이 프로젝트 대단합니다. 화이팅입니다.

yonglimlee님의 프로필 이미지
yonglimlee

작성한 질문수

질문하기