如果您有一个带有BottomNavigationBar的应用程序,并且要从一个barItem切换到另一barItem并返回给您列出Stream或Future,则我已经将scaffoldKey用于BottomNavigationBar,将PageStorageKey用于列表...我想逐页加载(分页)多数民众赞成的集合,但是使用Future或StreamBuilder在此或海峡中获取相同的结果...
您总是首先看到加载...但是加载是从本地而不是从Firestore数据库进行的吧?有没有办法再次跳过此加载... ??
class ListPage extends StatefulWidget {
final FirebaseAnalytics analytics;
final FirebaseAnalyticsObserver observer;
final Firestore firestore;
ListPage({Key key, this.analytics, this.observer, this.firestore})
: super(key: key);
@override
_ListPageState createState() => new _ListPageState();
}
class _ListPageState extends State<ListPage> {
final Firestore firestore = Firestore();
RemoteConfig remoteConfig;
final TextEditingController _search = new TextEditingController();
SearchTextBox _searchField;
ScrollController controller;
DocumentSnapshot _lastVisible;
bool _isLoading;
CollectionReference get homeFeeds => firestore.collection('collection');
List<DocumentSnapshot> _data = new List<DocumentSnapshot>();
final scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
Analytics().setCurrentScreen('collection', 'listPage');
controller = new ScrollController()..addListener(_scrollListener);
_isLoading = true;
_getData();
}
Future<Null> _getData() async {
QuerySnapshot data;
if (_lastVisible == null) {
data = await firestore
.collection('collection')
.orderBy('updated_at', descending: true)
.limit(50)
.getDocuments();
print('lastVisible == null');
} else {
data = await firestore
.collection('collection')
.orderBy('updated_at', descending: true)
.startAfter([_lastVisible['updated_at']])
.limit(10)
.getDocuments();
print('lastVisible else');
}
if (data != null && data.documents.length > 0) {
_lastVisible = data.documents[data.documents.length - 1];
if (mounted) {
setState(() {
print('lastVisible != null && data.documents.length > 0');
_isLoading = false;
_data.addAll(data.documents);
});
}
} else {
setState(() => _isLoading = false);
// scaffoldKey.currentState?.showSnackBar(
// SnackBar(
// content: Text('No more restaurants!'),
// ),
// );
}
return null;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
key: scaffoldKey,
body: ListView.builder(
shrinkWrap: true,
controller: controller,
itemCount: _data.length + 1,
itemBuilder: (_, int index) {
if (index < _data.length) {
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
isThreeLine: false,
key: PageStorageKey(index),
title: Text('text'),
subtitle: Text(
'${_data[index].data['name']} • ${_data[index].data['place']}',
),
onTap: () {},
leading: InkWell(
child: Container(
height: 110.0,
width: 50.0,
child: Placeholder(),
)),
),
),
new Divider(
height: 2.0,
),
],
);
}
return Center(
child: Opacity(
opacity: _isLoading ? 1.0 : 0.0,
child: SizedBox(
width: 32.0,
height: 32.0,
child: CircularProgressIndicator()),
),
);
},
),
);
}
@override
void dispose() {
controller.removeListener(_scrollListener);
super.dispose();
}
void _scrollListener() {
if (!_isLoading) {
double maxScroll = controller.position.maxScrollExtent;
double currentScroll = controller.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.65;
if (maxScroll - currentScroll < delta) {
setState(() => _isLoading = true);
_getData();
}
}
}
}