可滑动组件有时位于其他组件之上,有时位于其他组件之下 - FLUTTER

问题描述 投票:0回答:1

描述:

我在 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),
                        )),
                      ],
                    ))),
    );
  }

我尝试过的:

  • 我尝试了不同的堆栈和定位配置。

我想要的:

  • 我希望所有滑块始终位于其他组件之上。
android ios flutter dart mobile
1个回答
0
投票

我通过修改

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

提供
© www.soinside.com 2019 - 2024. All rights reserved.