Boxshadow отображается за другими виджетами

#flutter #flutter-layout

#flutter #flutter-layout (флаттер-макет)

Вопрос:

Вверху страницы у меня есть Container с BoxShadow оформлением, а под Container находится ListView с Cards числом в нем. Я хочу, чтобы вверху Container была тень, которая появляется перед элементами в ListView , но это то, что я получаю:

введите описание изображения здесь

Кажется, что отбрасываемая тень появляется позади Cards , а не перед ним. Это код:

 Widget _buildBody(BuildContext context, ChecklistModel model){
    return Container(
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
                Container(
                    decoration: BoxDecoration(
                        color: Colors.red.shade200,
                        boxShadow: [BoxShadow(
                            color: Colors.red.shade200,
                            offset: Offset(0, 10),
                            blurRadius: 10,
                            spreadRadius: 10
                        )]
                    ),
                    child: ListTile(
                        title: Text(''),
                    )
                ),
                Expanded(child: Padding(
                    padding: const EdgeInsets.all(10),
                    child: _buildCheckpointListView(context, model))
                )
            ],
        )
    );
}
  

Я также пытался заменить Container на Card , но это тоже не сработало.

Комментарии:

1. Мой случай — верхний виджет. Итак, я решил, поместив Container как AppBar и ListView как тело каркаса. Поэтому тени контейнера могут отображаться нормально.

Ответ №1:

Это происходит потому, что, поскольку вы используете Expanded виджет внутри Column , он занимает все доступное пространство на экране и, следовательно, выглядит так, как будто он перекрывает Container , но на самом деле это просто перекрывающая тень.

Вместо Column виджета используйте Stack для отображения Container над ListView . Вы можете использовать Positioned виджет для позиционирования дочерних виджетов стека.

Но в этом случае убедитесь, что вы поместили Container код после ListView кода, чтобы он всегда был сверху.

Пример:

 Stack(
  children: <Widget>[
    Padding(
      padding: const EdgeInsets.all(10),
      child: _buildCheckpointListView(context, model)
    ),
    Positioned(
      top: 0.0, //To align Container at the top of screen
      left: 0.0,
      right: 0.0,
      child: Container(
        decoration: BoxDecoration(
          color: Colors.red.shade200,
          boxShadow: [
            BoxShadow(
              color: Colors.red.shade200,
              offset: Offset(0, 10),
              blurRadius: 10,
              spreadRadius: 10
          )]
        ),
        child: ListTile(
          title: Text(''),
        )
     ),
    ),
  ]
)
  

Вы также можете поместить себя ListView внутрь Positioned виджета, если хотите обеспечить определенное расстояние сверху.

Комментарии:

1. Мило! Но ListView определенно должен быть смещен от вершины, иначе верхний элемент списка будет закрыт Контейнером и, следовательно, недоступен. Есть идеи, как этого добиться, если высота контейнера неизвестна?

Ответ №2:

Выделите нижнее поле для контейнера, чтобы ввести некоторое пустое пространство между контейнером и нижними братьями и сестрами. Вот так :

         Container(
        margin: EdgeInsets.only(bottom: 20),
          decoration: BoxDecoration(
              color: Colors.red.shade200,
              boxShadow: [BoxShadow(
                  color: Colors.red.shade200,
                  offset: Offset(0, 10),
                  blurRadius: 10,
                  spreadRadius: 10
              )]
          ),
          child: ListTile(
            title: Text(''),
          )
      ),
  

Комментарии:

1. Это действительно улучшает внешний вид, но на самом деле другие виджеты не помещаются за отбрасываемой тенью, они просто помещаются под ней…

2. Это может быть немного сложно, так как в случае двух перекрывающихся виджетов виджет, который находится ниже в коде макета, перекрывает предыдущий. Вы можете задать элементам списка непрозрачность менее 1.