Как предотвратить перекрытие AppBar Overlay?

avatar
Warwick
1 июля 2021 в 19:58
165
2
2

У меня есть собственный виджет, расположенный в Stack. Этот пользовательский виджет создает элемент OverlayEntry, связанный со своим положением, и вставляет его в элемент Overlay.

.

Проблема в том, что это наложение всплывает над AppBar и FloatingActionButton.

Как поместить OverlayEntry под AppBar, но над содержимым моего Stack?

UPD: Под "ниже" я имею в виду, что AppBar должен плавать над OverlayEntry (или перекрывать его, как если бы он имел больший z-индекс).

Вот что у меня есть:

enter image description here

Вот что я хотел бы иметь:

enter image description here

Код образца:

import 'package:flutter/material.dart';

main() {
  runApp(
    MaterialApp(
      home: OverlayDemo(),
    ),
  );
}

class OverlayDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AppBar + Overlay'),
      ),
      body: Stack(
        children: [
          Positioned(
            top: 10,
            left: 100,
            child: WidgetWithOverlay()
          )
        ],
      )
    );
  }
}


class WidgetWithOverlay extends StatefulWidget {
  const WidgetWithOverlay({
    Key? key,
  }) : super(key: key);

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

class _WidgetWithOverlayState extends State<WidgetWithOverlay> {
  OverlayEntry? overlayEntry;

  void showOverlay() {
    print(overlayEntry);
    if (overlayEntry == null) {
      overlayEntry = OverlayEntry(
          builder: (BuildContext context) {
            return Positioned(
                top: 0.0,
                left: 0.0,
                child: IgnorePointer(
                  child: Container(
                    width: 100,
                    height: 100,
                    color: Colors.green,
                  ),
                )
            );
          }
      );
      Overlay.of(context)!.insert(overlayEntry!);
    }
  }

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: showOverlay,
      child: Text('Show Overlay')
    );
  }
}
Источник
Why_So_Ezz
1 июля 2021 в 20:58
0

Оберните леса с помощью SafeArea()

Warwick
1 июля 2021 в 21:44
0

@Why_So_Ezz Не думаю, что это поможет.

Ответы (2)

avatar
Rai Rizwan
1 июля 2021 в 20:23
1

поместите стек над каркасом, тогда первый дочерний элемент стека будет вторым дочерним каркасом WidgetWithOverlay().

avatar
stacker
1 июля 2021 в 20:18
0

по умолчанию высота Appbar равна kToolbarHeight, поэтому вы можете создать наложение следующим образом:

  overlayEntry = OverlayEntry(
      builder: (BuildContext context) {
        return Positioned(
            top: kToolbarHeight,
            left: 0.0,
            child: IgnorePointer(
              child: Container(
                width: 100,
                height: 100,
                color: Colors.green,
              ),
            )
        );
      }
  );
Warwick
1 июля 2021 в 21:49
0

Я думаю, что я не использовал правильную формулировку для того, что я ищу. Я имею в виду, что OverlayEntry должно быть покрыто AppBar. Так что у него должен быть более низкий z-индекс, если это подходящий термин.