작성
·
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 = [];
헛 바로 해결되었네요!! ㅎㅎ 감사합니다.
setState()를 하게 되면 build(){} 안에 화면을 다시 그린다고 보면되는걸까요?