Я сталкиваюсь с проблемой состояния при использовании провайдеров StreamProvider, использующих базу данных firestore. Приложение получает объекты и отображает их в списке над ListView.builder. Теперь я хочу, чтобы пользователь изменил настройки, чтобы он / она мог фильтровать результаты по своим предпочтениям. Поскольку я новичок в флаттере и разработке приложений в целом, я не знаю, как заставить это работать. Вот основной код:
return StreamProvider<List<Cocktails>>.value(
value: CocktailsDatabase().cocktails,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: isSearching? TextFormField(
onChanged: (value){
setState(() {
searchQuery = value;
});
},
style: TextStyle(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 18.0),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Zoek naar cocktails...',
hintStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.w200),
contentPadding: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
fillColor: Colors.white,
icon: IconButton(
onPressed: (){
setState(() {
isSearching = false;
});
},
icon: Icon(Icons.close, color: Colors.white),
)
),
): Center(
child: Image.asset('assets/images/logo_white_large_textonly.png',
fit: BoxFit.contain,
height: 50,
width: 120,
)),
actions: <Widget>[
FlatButton.icon(
onPressed: (){
if (isSearching == false){
setState(() {
isSearching = true;
});
} else{
setState(() {
isSearching = false;
});
}
},
icon: isSearching? Icon(Icons.arrow_forward, color: Colors.white) : Icon(Icons.search,color: Colors.white),
label: Text('')),
],
),
body: CocktailList(),
floatingActionButton: FloatingActionButton(
onPressed: _showFiltersPanel,
child: Icon(Icons.tune),
backgroundColor: Colors.red,
),
)
);
}
void _showFiltersPanel(){
showModalBottomSheet(context: context,
elevation: 20.0,
builder: (context){
return Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
child: FilterForm(),
);
});
}
Где CocktailList () - это отдельный виджет для построения списка объектов, а _shoFiltersPanel - это отдельная встроенная функция для рисования нижнего листа на экране для изменения настроек поиска.
Код CocktailList ():
class CocktailList extends StatefulWidget {
@override
_CocktailListState createState() => _CocktailListState();
}
class _CocktailListState extends State<CocktailList> {
@override
Widget build(BuildContext context) {
final List<String> orderList = ['A-Z', 'Z-A', 'Meest favoriet'];
double searchTime;
double searchDifficulty;
double searchStrength;
String order;
bool alcoholic = true;
Cocktails cocktail;
List cocktails = Provider.of<List<Cocktails>>(context);
List filteredCocktails = [];
return ListView.builder(
itemCount: cocktails.length,
itemBuilder: (context, index){
return CocktailCard(cocktail: cocktails[index]);
},
);
}
}
где неиспользуемые переменные используются для изменения настроек того, при каких условиях строить список. Эти переменные можно изменить в de FilterForm () с помощью кода:
class _FilterFormState extends State<FilterForm> {
final List<String> orderList = ['A-Z', 'Z-A', 'Meest favoriet'];
double searchTime;
double searchDifficulty;
double searchStrength;
String order;
bool alcoholic = true;
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Bereidingstijd'),
Slider(
value: (searchTime ?? 1.0),
min: 1.0,
max: 10.0,
divisions: 9,
onChanged: (val) => setState(() => searchTime = val),
activeColor: Colors.red,
inactiveColor: Colors.redAccent,
label: searchTime.toString(),
),
Text('Moeilijkheid'),
Slider(
value: (searchDifficulty ?? 1.0),
min: 1.0,
max: 5.0,
divisions: 4,
onChanged: (val) => setState(() => searchDifficulty = val),
activeColor: Colors.red,
inactiveColor: Colors.redAccent,
label: searchDifficulty.toString(),
),
Text('Sterkte'),
Slider(
value: (searchStrength ?? 1.0),
min: 1.0,
max: 10.0,
divisions: 9,
onChanged: (val) => setState(() => searchStrength = val),
activeColor: Colors.red,
inactiveColor: Colors.redAccent,
label: searchStrength.toString(),
),
],
),
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
DropdownButton(
value: order ?? 'A-Z',
onChanged: (newOrder){
setState(() {
order = newOrder;
});
},
icon: Icon(Icons.sort),
items: orderList.map((order){
return DropdownMenuItem(
value: order,
child: Text('$order'),
);
}).toList()
),
Text('Alcoholisch'),
Switch(
value: alcoholic,
activeColor: Colors.red,
onChanged: (bool state){
setState(() {
alcoholic = state;
});
},
),
SizedBox(
height: 50.0,
width: 150.0,
child: Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: (){},
child: Icon(Icons.search),
backgroundColor: Colors.red,
),
),
),
],
)
],
);
}
}
Помощь будет потрясающей!