描述:
我在 Flutter 中的
Slidable
中遇到了 ListView
组件的问题。 Slidable
组件的行为根据列表中的项目数量而不一致。
问题:
ListView
没有足够的项目需要滚动时,Slidable
组件在滑动时会出现在所有其他组件的顶部。ListView
有足够的项目来启用滚动时,Slidable
组件在滑动时会位于其他组件下方。问题视频:
代码:
/* Events.dart */
Widget build(BuildContext context) {
return Container(
clipBehavior: Clip.none,
margin: const EdgeInsets.only(top: 5, bottom: 5, left: 10, right: 10),
child: ListView.builder(
itemCount: widget.lista.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Stack(clipBehavior: Clip.none, children: [
Positioned.fill(
child: Row(
children: [
Expanded(
child: Container(
margin: const EdgeInsets.only(bottom: 6),
decoration: const BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.all(Radius.circular(8))),
),
),
],
),
),
Slidable(
key: UniqueKey(),
endActionPane: ActionPane(
extentRatio: 0.2,
motion: const BehindMotion(),
children: [
GestureDetector(
onTap: () {
delete(context, widget.lista[index]);
},
child: Container(
margin: const EdgeInsets.only(bottom: 6),
padding: const EdgeInsets.only(left: 30),
decoration: const BoxDecoration(
borderRadius: BorderRadius.horizontal(
right: Radius.circular(15)),
color: Colors.red,
),
alignment: Alignment.center,
child: const Icon(Icons.delete_forever,
color: Colors.white),
),
),
]),
child: GestureDetector(
onTap: () {
Navigator.of(context).push(widget.action(
fetchRep: widget.fetchRep,
data: widget.data,
update: widget.update,
action: "mod_el",
report: widget.lista[index]));
},
child: Container(
padding: const EdgeInsets.all(10),
margin: const EdgeInsets.only(bottom: 6),
// margin: const EdgeInsets.fromLTRB(10, 3, 10, 3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.white, width: 1),
color: HexColor.fromHex(widget.lista[index].color),
),
child: Row(
children: [
Row(
children: [
Icon(
widget.lista[index].reportType == "R"
? Icons.assignment
: Icons.bookmark,
color: Colors.white,
size: 20,
),
const SizedBox(
width: 10,
),
],
),
Center(
child: Text(
"[ ${int.parse(widget.lista[index].quantity).toStringAsFixed(2)} ${widget.lista[index].unityCode} ]",
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold),
),
),
const SizedBox(
width: 20,
),
Expanded(
child: Text(
"${widget.lista[index].customerCode} - ${widget.lista[index].taskTypeCode}",
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
],
),
),
),
),
]);
},
),
);
}
/* ContainerEvents.dart */
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 15),
child: AnimatedVisibility(
enter: fadeIn(),
exit: fadeOut(),
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.tertiaryContainer,
),
child: widget.loading
? Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color:
Theme.of(context).colorScheme.onTertiaryContainer,
size: 80,
),
)
: Column(
children: [
const SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"${DateFormat.EEEE('it_IT').format(widget.selezionato)}, ${DateFormat.MMMd('it_IT').format(widget.selezionato)}, ${DateFormat.y('it_IT').format(widget.selezionato)}",
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onTertiaryContainer,
fontSize:
MediaQuery.of(context).size.height /
100 *
2.5,
fontWeight: FontWeight.bold)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context)
.colorScheme
.inverseSurface,
),
onPressed: () {
showModalBottomSheet(
transitionAnimationController:
AnimationController(
vsync: Navigator.of(context),
duration: const Duration(
milliseconds: 600))
..forward(),
context: context,
isScrollControlled: true,
builder: (context) => Filterbox(
fetchRep: widget.fetchRep,
data: widget.data,
aggiornaData: widget.dayReload),
);
},
child: Icon(
Icons.filter_alt,
color: Theme.of(context).colorScheme.surface,
))
],
),
const SizedBox(
height: 10,
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Events(
data: widget.selezionato,
lista: widget.lista,
action: widget.createRoute,
fetchRep: widget.fetchRep,
update: widget.update),
)),
],
))),
);
}
我尝试过的:
我想要的:
我通过修改
Events.dart
文件解决了该问题。这是我添加的内容:
/* Events.dart */
class VerticalClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = Path();
path.moveTo(-double.maxFinite, 0);
path.lineTo(double.maxFinite, 0);
path.lineTo(double.maxFinite, size.height);
path.lineTo(-double.maxFinite, size.height);
path.close();
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
class _EventsState extends State<Events> {
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 5, bottom: 5, left: 10, right: 10),
child: ClipPath(
clipper: VerticalClipper(),
child: ListView.builder(
padding: const EdgeInsets.only(top: 1.0),
itemCount: widget.lista.length,
shrinkWrap: true,
clipBehavior: Clip.none,
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Stack(children: [
// Your item builder logic here
...
});
},
),
);
}
}
问题在于
Clip
创建了一个与容器一样大的框架,这阻止了滑块超出它。通过这样做,Clip
将与它所在的组件一样高,而宽度将等于手机的宽度。
解决方案由@Francesco Rasi
提供