我在ListView.builder();
中有一个showModalBottomSheet();
需要选择/取消选择多个项目,一切都很好,但是需要关闭模式并再次显示以应用更改,另一件事是ListTiles
有时重复多次,而功能emptyList
却没有工作正常。
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:flutter/material.dart';
import 'book_details.dart' show BookDetails;
class Explore extends StatefulWidget {
@override
_ExploreState createState() => _ExploreState();
}
var _books,
_categories,
_arranges,
_currentCategory,
_selected,
_primeColor,
_currentFilter,
_isThereIsFilters,
_booksContainer,
_booksWithFilters,
_isLoading,
_noBooks,
_itemIcon;
final GlobalKey<ScaffoldState> _scaffoldKeyExplore =
new GlobalKey<ScaffoldState>();
List<String> _getCats = new List();
List<String> _getArrs = new List();
void _insertCategories() {
for (int i = 0; i < _categories.length; i++) {
_getCats.add(_categories[i]);
}
_getCats.sort();
}
void _insertArranges() {
for (int i = 0; i < _arranges.length; i++) {
_getArrs.add(_arranges[i]);
}
}
class _ExploreState extends State<Explore> with TickerProviderStateMixin {
onCatChange(String category) {
setState(() {
_currentCategory = category;
});
}
@override
void initState() {
super.initState();
_primeColor = Color.fromRGBO(239, 89, 39, 1.0);
_categories = ["أول", "ثاني", "ثالث", "رابع", "خامس"];
_arranges = ["أول", "ثاني", "ثالث", "رابع", "خامس"];
_currentFilter = _arranges[0];
_selected = [];
_isThereIsFilters = false;
}
void emptyList(List list) {
for (var i = 0; i < list.length; i++) {
list.remove(list[i]);
}
}
_showSheet(String type) {
switch (type) {
case "filters":
showModalBottomSheet(
context: _scaffoldKeyExplore.currentContext,
builder: (BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Container(
child: Column(children: <Widget>[
Expanded(
child: new ListView.builder(
itemCount: _getArrs[0] != null ? _getArrs.length : 0,
itemBuilder: (BuildContext context, int i) {
return new RadioListTile(
title: Text(_getArrs[i]),
value: _getArrs[i],
groupValue: _currentFilter,
onChanged: (val) {
setState(() {
_currentFilter = val;
});
});
}),
)
])),
);
});
break;
case "categories":
default:
showModalBottomSheet(
context: _scaffoldKeyExplore.currentContext,
builder: (BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Container(
child: Column(children: <Widget>[
Container(
color: _primeColor,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
IconButton(
icon: Icon(Icons.close, color: Colors.white),
onPressed: () {
emptyList(_selected);
//Navigator.pop(context);
//_showSheet(type);
}),
IconButton(
icon:
Icon(Icons.done_all, color: Colors.white),
onPressed: () {
if (_selected.length > 0) {
_getFilteredBooks(_selected);
setState(() {
_isThereIsFilters = true;
});
} else {
setState(() {
_isThereIsFilters = false;
});
}
Navigator.pop(context);
})
]),
),
Expanded(
child: new ListView.builder(
itemCount: _getCats != null ? _getCats.length : 0,
itemBuilder: (BuildContext context, int i) {
final _isSelected = _selected.contains(_getCats[i]);
return new ListTile(
leading: Icon(Icons.category),
trailing: _isSelected ? Icon(Icons.done) : null,
title: Text(_getCats[i]),
onTap: () {
setState(() {
_isSelected
? _selected.remove(_getCats[i])
: _selected.add(_getCats[i]);
});
//Navigator.pop(context);
//_showSheet(type);
});
}),
)
])),
);
});
break;
}
}
@override
Widget build(BuildContext context) {
return new Directionality(
textDirection: TextDirection.rtl,
child: new Scaffold(
key: _scaffoldKeyExplore,
appBar:
AppBar(title: Text("استكشاف"), elevation: 0.0, actions: <Widget>[
IconButton(
icon: Icon(Icons.category, color: _primeColor),
onPressed: () => _showSheet("categories")),
IconButton(
icon: Icon(Icons.filter_list, color: _primeColor),
onPressed: () => _showSheet("filters"))
]),
body: Center(child: Text("Nothing..."));
));
}
}
谢谢
答案 0 :(得分:0)
需要关闭模式并再次显示以应用更改
之所以会这样,是因为需要再次调用showModalBottomSheet
的{{1}}来反映所做的更改。
在Flutter中,builder
应当能够在状态改变的任何时间重建-此处不是这种情况,因为显示了底页。
我为什么会遇到此问题(在元级别上)?
将状态存储在StatefulWidget
中对于保存UI状态很有用,但是如果要存储某些“应用程序状态”或“数据状态”,而该状态与屏幕所在的屏幕无关,则可以快速淘汰此技术。
现在是时候从根本上重新考虑您的状态管理,并采用一种成熟的状态管理模式,该模式将状态与小部件分离。幸运的是,有一些可供选择:
StatefulWidget
的合同(可以在不通知小部件的情况下修改状态)。另外,您还会中断热重启以及类似的操作。setState
,其中根窗口小部件下方的窗口小部件可以访问相同的状态。InheritedWidget
,它是基于此的。ScopedModel
的顶部,但是增加了一些InheritedWidget
-y的东西,以使所有内容都变得更加被动。这是一个很棒的Youtube video about state management from Google I/O,其中展示了几种模式。
无论如何,底页是正确的摆设吗?
根据the Material Design spec,模态底页是“内联菜单或移动设备上简单对话框的替代方案,为其他项目,较长的描述和图示提供了空间”。
更具体地讲,Stream
函数旨在显示一个随时间变化不会影响父级的小部件,而是(如果有的话)在单个时间点上影响小部件。这就是为什么它返回showModalBottomSheet
而不是Future<T>
的原因。
请注意,您正在尝试以不希望使用的方式使用底部纸。 对于您的情况,建议您仅使用一个新屏幕。