Flutter NeverScrollableScrollPhysics 分页不起作用
Flutter NeverScrollableScrollPhysics pagenation not work
我正在尝试使用分页绑定 NestedScrollView
和 GridView
。
但是我把NeverScrollableScrollPhysics()
放在了GridView
里,分页功能不起作用
估计是scrollcontroller引起的
我该如何解决这个问题?
我会附上我的代码。
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
//infinite scroll
List<DocumentSnapshot> products = []; // stores fetched products
bool isLoading = false; // track if products fetching
bool hasMore = true; // flag for more products available or not
int documentLimit = 20; // documents to be fetched per request
DocumentSnapshot
lastDocument; // flag for last document from where next 10 records to be fetched
ScrollController _scrollController =
ScrollController(); // listener for listview scrolling
@override
void initState() {
getProducts();
_scrollController.addListener(() {
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.20;
if (maxScroll - currentScroll <= delta) {
getProducts();
}
});
}
@override
void dispose() {
_scrollController?.dispose();
super.dispose();
}
getProducts() async {
//...
//get items from firebase
//...
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.backgroundwhite,
title: Image(
width: 132.0,
height: 40.0,
image: AssetImage('images/logo_horiz.png'),
),
),
body: NestedScrollView(
headerSliverBuilder: (context, isScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildListDelegate([
Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"다른 유저가 키우는",
style: TextStyle(
fontSize: 24.0,
color: Colors.black,
fontWeight: FontWeight.w200,
fontFamily: "Roboto"),
),
Padding(padding: EdgeInsets.fromLTRB(0, 0, 0, 5.0)),
Row(
children: <Widget>[
Text(
"율마",
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
Text(
"가 궁금하신가요?",
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
fontWeight: FontWeight.w200,
fontFamily: "Roboto"),
),
],
),
Padding(padding: EdgeInsets.fromLTRB(0, 0, 0, 25.0)),
Container(
color: Colors.transparent,
width: double.infinity,
height: 46,
child: FlatButton(
color: Theme.of(context).colorScheme.lightGrey,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchPage()),
);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
child: Row(
children: <Widget>[
Icon(Icons.search,
size: 30.0, color: Colors.black12),
Padding(
padding:
const EdgeInsets.only(right: 10.0),
),
Text(
"율마",
style: new TextStyle(
fontSize: 20.0,
color: Theme.of(context)
.colorScheme
.textBlack,
fontWeight: FontWeight.w200,
fontFamily: "Roboto"),
)
],
))),
]),
),
]))
];
},
body: LayoutBuilder(
builder:(BuildContext context, BoxConstraints viewportConstraints) {
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(children: <Widget>[
Flexible(
// this will host our Tab Views
child: GridView.builder(
// physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
controller: _scrollController,
itemCount: products.length,
itemBuilder: (context, index) {
return _buildListItem(context, products[index]);
},
)),
])));
}),
));
}
Widget _buildListItem(BuildContext context, item) {
return Hero(
tag: item.documentID,
child: Material(
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPostPage(item)),
);
},
child: Image.network(item['imageUrls'][0]['url'], fit: BoxFit.cover),
),
),
);
}
}
非常感谢
哦!最后我用 CustomScrollView
而不是 NestedScrollview
.
解决了这个问题
此外,我将 CustomScrollView
包装为 LayoutBuilder
。
因此 Scaffold
正文部分的最终代码如下:
LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: CustomScrollView(
// physics: AlwaysScrollableScrollPhysics(),
controller: _scrollController,
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
_buildHeader()
])),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return _buildListItem(context, products[index]);
},
childCount: products.length,
),
)
]
)
);
}),
希望对您有所帮助!
我正在尝试使用分页绑定 NestedScrollView
和 GridView
。
但是我把NeverScrollableScrollPhysics()
放在了GridView
里,分页功能不起作用
估计是scrollcontroller引起的
我该如何解决这个问题?
我会附上我的代码。
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
//infinite scroll
List<DocumentSnapshot> products = []; // stores fetched products
bool isLoading = false; // track if products fetching
bool hasMore = true; // flag for more products available or not
int documentLimit = 20; // documents to be fetched per request
DocumentSnapshot
lastDocument; // flag for last document from where next 10 records to be fetched
ScrollController _scrollController =
ScrollController(); // listener for listview scrolling
@override
void initState() {
getProducts();
_scrollController.addListener(() {
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.20;
if (maxScroll - currentScroll <= delta) {
getProducts();
}
});
}
@override
void dispose() {
_scrollController?.dispose();
super.dispose();
}
getProducts() async {
//...
//get items from firebase
//...
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.backgroundwhite,
title: Image(
width: 132.0,
height: 40.0,
image: AssetImage('images/logo_horiz.png'),
),
),
body: NestedScrollView(
headerSliverBuilder: (context, isScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildListDelegate([
Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"다른 유저가 키우는",
style: TextStyle(
fontSize: 24.0,
color: Colors.black,
fontWeight: FontWeight.w200,
fontFamily: "Roboto"),
),
Padding(padding: EdgeInsets.fromLTRB(0, 0, 0, 5.0)),
Row(
children: <Widget>[
Text(
"율마",
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
Text(
"가 궁금하신가요?",
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
fontWeight: FontWeight.w200,
fontFamily: "Roboto"),
),
],
),
Padding(padding: EdgeInsets.fromLTRB(0, 0, 0, 25.0)),
Container(
color: Colors.transparent,
width: double.infinity,
height: 46,
child: FlatButton(
color: Theme.of(context).colorScheme.lightGrey,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchPage()),
);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
child: Row(
children: <Widget>[
Icon(Icons.search,
size: 30.0, color: Colors.black12),
Padding(
padding:
const EdgeInsets.only(right: 10.0),
),
Text(
"율마",
style: new TextStyle(
fontSize: 20.0,
color: Theme.of(context)
.colorScheme
.textBlack,
fontWeight: FontWeight.w200,
fontFamily: "Roboto"),
)
],
))),
]),
),
]))
];
},
body: LayoutBuilder(
builder:(BuildContext context, BoxConstraints viewportConstraints) {
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(children: <Widget>[
Flexible(
// this will host our Tab Views
child: GridView.builder(
// physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
controller: _scrollController,
itemCount: products.length,
itemBuilder: (context, index) {
return _buildListItem(context, products[index]);
},
)),
])));
}),
));
}
Widget _buildListItem(BuildContext context, item) {
return Hero(
tag: item.documentID,
child: Material(
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPostPage(item)),
);
},
child: Image.network(item['imageUrls'][0]['url'], fit: BoxFit.cover),
),
),
);
}
}
非常感谢
哦!最后我用 CustomScrollView
而不是 NestedScrollview
.
此外,我将 CustomScrollView
包装为 LayoutBuilder
。
因此 Scaffold
正文部分的最终代码如下:
LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: CustomScrollView(
// physics: AlwaysScrollableScrollPhysics(),
controller: _scrollController,
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
_buildHeader()
])),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return _buildListItem(context, products[index]);
},
childCount: products.length,
),
)
]
)
);
}),
希望对您有所帮助!