Я новичок в разработке Flutter и только начал с gridViewWidget. В моем представлении сетки у меня есть FlashCardList и FlashCards. На самом высоком уровне он должен отображать FlashCardList и onTap на любом из объектов, он должен отображать другое представление сетки с карточками, связанными с категорией flashCardList. Мой вопрос: нужно ли мне создавать новый gridViewWidget только для FlashCards и повторять 90% кода, или я могу повторно использовать существующий виджет? Я могу сделать это в iOS, снова вызвав одно и то же представление и передав несколько значений, чтобы дочернее представление знало, что нужно получить другой набор данных, но я не уверен, как я могу сделать это с помощью futurebuilder, который запрашивает тип должны быть предопределены, и построитель gridView Builder, который также требует, чтобы элементы были предопределены. Вот мой код:
class GridViewWidget extends StatefulWidget{
@override
createState() => new GridViewState();
}
class GridViewState extends State<GridViewWidget>{
List<Sound> sound;
List<FlashCardList> flashCardList;
List<FlashCards> flashCards;
@override
void initState(){
debugPrint ('debug main.dart');
super.initState();
}
Future<List<FlashCards>> fetchFlashCards() async{
final response = await http.get('some url');
//debugPrint (response.body);
if (response.statusCode == 200) {
var data = json.decode(response.body);
var flashCardsData = data["FlashCards"] as List;
flashCards = flashCardsData.map<FlashCards>((json) => FlashCards.fromJson(json)).toList();
debugPrint("Did get data: ${flashCards.first.name}");
} else {
throw Exception('Failed to load post');
}
//objects = [sound, flashCardList, flashCards].expand((x) => x).toList();
return flashCards;
}
Future<List<FlashCardList>> fetchFlashCardList() async{
final response = await http.get('some url');
//debugPrint (response.body);
if (response.statusCode == 200) {
var data = json.decode(response.body);
var flashCardListData = data["FlashCardList"] as List;
flashCardList = flashCardListData.map<FlashCardList>((json) => FlashCardList.fromJson(json)).toList();
debugPrint("Did get data: ${flashCardList.first.name}");
} else {
throw Exception('Failed to load post');
}
//objects = [sound, flashCardList, flashCards].expand((x) => x).toList();
return flashCardList;
}
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(
centerTitle: true,
title: new Text(Strings.pageTitle),
),
body: FutureBuilder<List<FlashCardList>>(
future: fetchFlashCardList(),
builder: (BuildContext context, AsyncSnapshot<List<Object>> snapshot) {
if (snapshot.hasError)
return new Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Input a URL to start');
case ConnectionState.waiting:
return new Center(child: new CircularProgressIndicator());
case ConnectionState.active:
return new Text('');
case ConnectionState.done:
return new GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
childAspectRatio: MediaQuery.of(context).size.width/(MediaQuery.of(context).size.height)),
itemCount: flashCardList.length,
itemBuilder: (BuildContext context, int index) {
return _getGridItemUI(context, flashCardList[index]);
/*return GridTile(header: Text("FlashCards"),
child: Text(
flashCards[index].name, textAlign: TextAlign.center));*/
},
);
}
}
),
);
}
_getGridItemUI(BuildContext context, FlashCardList item){
return new InkWell(
onTap: () {
_showSnackBar(context, item);
},
child: new Card(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Image(image: new CachedNetworkImageProvider("some url" + item.image)),
/*new Expanded(
child:new Center(
child: new Column(
children: <Widget>[
new SizedBox(height: 8.0),
new Expanded(
child: AutoSizeText(
item.name, maxLines: 1,
)
)
],
),
)
)*/
],
),
elevation: 2.0,
margin: EdgeInsets.all(5.0),
)
);
}
_showSnackBar(BuildContext context, FlashCardList item){
}
}
Вы можете сделать GridViewWidget универсальным, чтобы решить проблему с типом, или передать параметр, чтобы различать флэш-память и флэш-карты, но это не идеальное решение. И я рекомендую не размещать логику выборки данных внутри ваших виджетов.
В этом случае, если вы извлечете бизнес-логику, объем кода, который вы будете дублировать, будет минимальным. Но опять же, это полностью зависит от ваших требований, если вы уверены, что эти два представления (flashcardList и детали списка) не будут иметь разных требований в будущем с одним gridView, но если есть даже небольшое изменение, я бы выбрал два представления. Вы можете извлечь _getGridItemUI в виджет и использовать его в обоих видах сетки.
спасибо, так что идеальным решением было бы иметь 2 виджета gridview?