有时候内容可能比较少,中间就会出现空白区域,但要求按钮要在最底部。但如果内容比较多,空白区域就会减少,如果屏幕都不够显示内容,那么就继续往下挤,使出现可滚动效果,这个时候是希望按钮也可以随着滚动,而不是始终保持在屏幕的底部。
有时候内容可能比较少,中间就会出现空白区域,但要求按钮要在最底部。但如果内容比较多,空白区域就会减少,如果屏幕都不够显示内容,那么就继续往下挤,使出现可滚动效果,这个时候是希望按钮也可以随着滚动,而不是始终保持在屏幕的底部。
试了一下,你参考参考:
import 'dart:async';
import 'package:flutter/material.dart';
class TestScreenPage extends StatefulWidget {
const TestScreenPage({Key? key}) : super(key: key);
@override
State<TestScreenPage> createState() => _TestScreenPageState();
}
class _TestScreenPageState extends State<TestScreenPage> {
List<String> lists = ['test 0'];
ScrollController scrollController = ScrollController();
GlobalKey centerKey = GlobalKey();
double? height;
@override
void initState() {
super.initState();
initItems();
}
void initItems() {
Timer.periodic(const Duration(milliseconds: 1000), (timer) {
lists.add('test ${lists.length}');
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Builder(builder: (ct) {
height ??= MediaQuery.of(ct).size.height;
final padding = MediaQuery.of(context).padding.vertical;
const buttonHeight = 52.0;
final centerPadding =
height! - 56 * lists.length - padding - buttonHeight;
print(
"height: $height, padding: $padding, centerPadding: $centerPadding");
return Container(
color: Colors.red,
child: CustomScrollView(
controller: scrollController,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(ct, index) => Container(
color: Colors.green,
height: 56,
child: Text(lists[index]),
),
childCount: lists.length,
),
),
SliverPadding(
key: centerKey,
padding: EdgeInsets.only(
top: centerPadding < 0 ? 0 : centerPadding),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ct, index) => TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(
const EdgeInsets.all(0)),
fixedSize: MaterialStateProperty.all(
const Size(double.infinity, buttonHeight)),
),
onPressed: () {},
child: const Text("button")),
childCount: 1,
),
),
],
),
);
}),
),
);
}
}
改成这样实现呢?
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
class TestScreenPage extends StatefulWidget {
const TestScreenPage({Key? key}) : super(key: key);
@override
State<TestScreenPage> createState() => _TestScreenPageState();
}
class _TestScreenPageState extends State<TestScreenPage> {
List<Map<String, dynamic>> lists = [
{'name': 'test 0', 'height': 56.0}
];
ScrollController scrollController = ScrollController();
GlobalKey centerKey = GlobalKey();
double? height;
bool canScroll = false;
bool firstBuild = false;
@override
void initState() {
super.initState();
initItems();
}
void initItems() {
scrollController.addListener(() {
print(scrollController.position);
if (!canScroll) {
setState(() => canScroll = true);
_jumpToMaxExtent();
}
});
Timer.periodic(const Duration(milliseconds: 1000), (timer) {
final height = Random().nextDouble() * 56;
setState(
() => lists.add({'name': 'test ${lists.length}', 'height': height}));
_jumpToMaxExtent();
});
}
Future _jumpToMaxExtent() async {
await Future.delayed(const Duration(milliseconds: 20));
scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 200),
curve: Curves.ease,
);
}
void afterBuild() {
firstBuild = true;
Future.delayed(const Duration(milliseconds: 200), () async {
final maxExtent = scrollController.position.maxScrollExtent;
if (maxExtent >= MediaQuery.of(context).size.height) {
setState(() => canScroll = true);
await Future.delayed(const Duration(milliseconds: 20));
scrollController.animateTo(
maxExtent,
duration: const Duration(milliseconds: 200),
curve: Curves.ease,
);
}
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Builder(
builder: (ct) {
Widget widget = Column(
children: [
Expanded(
child: ListView(
controller: scrollController,
physics: const ClampingScrollPhysics(),
children: List.generate(
lists.length,
(index) => Container(
color: Colors.red,
height: lists[index]['height'],
child: Text(lists[index]['name']),
),
),
),
),
TextButton(
style: ButtonStyle(
padding:
MaterialStateProperty.all(const EdgeInsets.all(0)),
),
onPressed: () {},
child: const Text("button")),
],
);
if (!firstBuild) afterBuild();
if (canScroll) {
widget = ListView(
controller: scrollController,
physics: const ClampingScrollPhysics(),
children: [
...List.generate(
lists.length,
(index) => Container(
color: Colors.black26,
height: lists[index]['height'],
child: Text(lists[index]['name']),
),
),
TextButton(
style: ButtonStyle(
padding:
MaterialStateProperty.all(const EdgeInsets.all(0)),
),
onPressed: () {},
child: const Text("button")),
],
);
}
return widget;
},
),
),
);
}
}
2 回答2k 阅读✓ 已解决
2 回答784 阅读✓ 已解决
1 回答735 阅读✓ 已解决
1 回答1.4k 阅读
1 回答1.2k 阅读
2 回答951 阅读
2 回答954 阅读