Стек: крышка нижнего дочернего элемента верхним дочерним элементом

#flutter #flutter-layout

#flutter #flutter-layout

Вопрос:

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

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

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

чего я хочу достичь:

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

 Row(
    crossAxisAlignment: CrossAxisAlignment.start,
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      Text(
        'Winner: ',
        style: TextStyle(fontSize: 34),
      ),
      Stack(
        children: [
          Text('YOU!!!', style: TextStyle(fontSize: 34)),
          Container(
            color: Colors.amber,
          )
        ],
      ),
    ],
  ),
 

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

Стек определяет размеры своих дочерних элементов на основе ограничения, которое он получает от родительского элемента, а не на основе размеров дочерних элементов.

как я могу наложить верхний виджет с точным размером нижнего виджета?

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

1. Помогает ли это ?

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

Ответ №1:

Чтобы узнать размер вашего widget и применить его в зависимости от этого, вы можете использовать GlobalKey следующим GlobalKey key; образом . Инициализируйте его в своем initSate и прослушайте его размер

 GlobalKey key;
double yourWidgetWidth;
double yourWidgetHeight;

@override
initState() {
   // .... other stuffs
   
   key = GlobalKey();

   WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) {
         yourWidgetWidth = containerKey.currentContext.size.width;
         yourWidgetHeight = containerKey.currentContext.size.height;
      }
   });
}
 

И с yourWidgetWidth помощью и yourWidgetHeight вы можете добиться того, чего хотите

Редактировать Вот концепция того, что я пытаюсь объяснить

 // In variable declaration scope
GlobalKey youTextKey = GlobalKey();
ValueNotifier widthNotifier = ValueNotifier(0);
ValueNotifier heightNotifier = ValueNotifier(0);

// In initState
WidgetsBinding.instance.addPostFrameCallback((_) {
  if (mounted) {
    widthNotifier.value = youTextKey.currentContext.size.width - 1.0;
    heightNotifier.value = youTextKey.currentContext.size.height - 5.0;
  }
});

// Your row
Row(
  crossAxisAlignment: CrossAxisAlignment.start,
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    Text(
      'Winner: ',
      style: TextStyle(fontSize: 34),
    ),
    Stack(
      children: [
        Text('YOU!!!', style: TextStyle(fontSize: 34), key: youTextKey,),
        ValueListenableBuilder(
          valueListenable: widthNotifier,
          builder: (context, width, _) {
            return ValueListenableBuilder(
              valueListenable: heightNotifier,
              builder: (context, height, _) {
                return Container(
                  width: width,
                  height: height,
                  color: Colors.amber,
                );
              },
            );
          },
        ),
      ],
    ),
  ],
)
 

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

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

2. Я сталкивался с подобными вещами в прошлом. Может быть, вы можете проверить мое новое редактирование

3. Спасибо за вклад, смотрите Ответ

Ответ №2:

Использование Positioned.Fill решило проблему:

Positioned.Fill Создает позиционированный объект с [слева], [сверху], [справа] и [снизу], равными 0.0, если для них не передано значение. таким образом, позиционированный дочерний элемент растягивается до краев самого большого дочернего элемента стека.

 Row(
    crossAxisAlignment: CrossAxisAlignment.start,
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      Text(
        'Winner: ',
        style: TextStyle(fontSize: 34),
      ),
      Stack(
        children: [
          Text('YOU!!!', style: TextStyle(fontSize: 34)),
          Positioned.fill(
            child: Container(
              color: Colors.amber,
            ),
          )
        ],
      ),
    ],
  ),
 

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

1. Действительно, это более эффективно!