Flutter阴影覆盖在其他小部件上。

9

我的基础小部件是Column。第一个元素是一个Container,它有一个BoxShadow。第二个元素是一个ListView,根据上下文构建了几个Card。如果滚动为0,则显示阴影。然而,当开始滚动时,Card会覆盖在阴影之上(z-index更高),并将其隐藏。

未滚动

未滚动时可见阴影

已滚动

进入图像描述

阴影应始终保持在Cards之上。如何实现这一点?


你能分享一些代码吗?还有一些预期的 UI 吗?截图看起来很白,细节无法理解。抱歉伙计! - Swaminathan V
3个回答

1
根据您的问题,这里是出现问题的概念。
“Column”的第一个子元素是一个带阴影的容器。 “Shadow”在定义的大小之外呈现。 如果您在此“Container”之后不提供任何空格,我们将无法看到阴影。 可以通过“Container margin”、“SizedBox”或“使用Padding包装我们的列表”来完成此空格。 但现在我们的主要问题是如何在索引=0时获得阴影。 我认为它来自“ListChildren”。它们包含上部空间,这就是为什么我们只能看到第一次的原因。
UI渲染的优先级从底部到顶部开始。
如何解决这个问题: 我们可以在容器底部提供空间或分配边距(而不是填充),或者在容器之后使用“SizedBox”,提供与“shadow”相同高度的同等空间。
  1. 在容器上提供底部margin
  2. 添加高度为阴影的SizedBox
  3. Padding包装我们的列表,并提供top:

在这张图片中,我们的shadow: whitebackground:amber

enter image description here

演示代码:

import 'package:flutter/material.dart';

class ColumnWithContainerShadow extends StatelessWidget {
  const ColumnWithContainerShadow({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amber,
      body: Column(
        children: [
          Container(
            height: 50,
            width: double.infinity,
            ////* we dont need margin if we have padding on ListView
            // margin: EdgeInsets.only(bottom: 12),
            decoration: BoxDecoration(
              color: Colors.green,
              boxShadow: [
                BoxShadow(
                  offset: Offset(0, 12),
                  color: Colors.white,
                )
              ],
            ),
            child: Center(child: Text("Container A")),
          ),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.only(top: 12),
              child: ListView(
                children: [
                  ...List.generate(
                    333,
                    (index) => Container(
                      /// enable this margine and remove other spaces to see 1st child shadow.(shadow depend on children position)
                      // margin: EdgeInsets.only(top: 12),
                      height: 60,
                      color: Colors.deepPurple,
                      child: Text("$index"),
                    ),
                  )
                ],
              ),
            ),
          ),
          Container(
            height: 50,
            width: double.infinity,
            alignment: Alignment.center,
            decoration: BoxDecoration(
              color: Colors.green,
              boxShadow: [
                BoxShadow(
                  offset: Offset(0, 12),
                  color: Colors.white,
                )
              ],
            ),
            child: Text("Bottom Container"),
          ),
          // Comment to close shadow
          SizedBox(
            height: 20,
          )
        ],
      ),
    );
  }
}


1

编辑

如果您不希望容器阴影在滚动时消失,请删除ScrollNotificationNotificationListener

有一个适用于此的小部件

您可以使用ScrollNotificationNotificationListener。尝试this;

编程愉快!

class TestPage extends StatefulWidget {
  const TestPage({Key key}) : super(key: key);

  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  double blurRadius = 10.0;
  double spreadRadius = 1.0;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blueGrey,
        title: Text('Title'),
      ),
      body: Container(
        width: Get.width,
        height: Get.height,
        child: Stack(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0).copyWith(
                top: 62.0,
              ),
              child: NotificationListener<ScrollNotification>(
                // ignore: missing_return
                onNotification: (scrollNotification) {
                  if (scrollNotification is ScrollStartNotification) {
                    setState(() {
                      blurRadius = 0.0;
                      spreadRadius = 0.0;
                    });
                  } else if (scrollNotification is ScrollEndNotification) {
                    setState(() {
                      blurRadius = 10.0;
                      spreadRadius = 1.0;
                    });
                  }
                },
                child: ListView.builder(
                  // controller: _controller,
                  itemCount: 10,
                  itemBuilder: (context, index) {
                    return Card(
                      child: Container(
                          width: Get.width * .8,
                          height: 100.0,
                          child: Center(
                            child: Text('child @ index : $index'),
                          )),
                    );
                  },
                ),
              ),
            ),
            Positioned(
              top: 0,
              left: 0,
              right: 0,
              child: Container(
                width: Get.width,
                height: 60.0,
                margin: EdgeInsets.only(),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                    bottomLeft: Radius.circular(20.0),
                    bottomRight: Radius.circular(20.0),
                  ),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.grey,
                      blurRadius: blurRadius,
                      spreadRadius: spreadRadius,
                    ),
                  ],
                ),
                child: Center(
                  child: Text('TOP CONTAINER'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

1
将此上方框包裹在 Material 组件中并提供一个高度。

高度并不是实际的 z-index。 - user3808307
https://material.io/design/environment/elevation.html - Rahul
高度(elevation)与 z-index 没有关系。它被称为高度,但只提供阴影效果。 - user3808307

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接