代码之家  ›  专栏  ›  技术社区  ›  Kdwk

为什么添加这个Flutter小部件会使应用程序对鼠标点击没有响应?

  •  0
  • Kdwk  · 技术社区  · 11 月前

    我正在写一个Flutter应用程序,并在桌面上运行它。其中一个页面有一个列,其中以下小部件是第一个子项:

    class HeroBanner extends StatelessWidget {
      String? image;
      String title = "";
      double maxHeight = 400;
    
      HeroBanner({Key? key, this.image, this.title = "", this.maxHeight = 100});
    
      @override
      Widget build(BuildContext context) {
        final theme = Theme.of(context);
    
        return image != null
            ? LayoutBuilder(builder: (context, constraints) {
                return ClipRect(
                  clipBehavior: Clip.hardEdge,
                  child: SizedBox(
                    height: maxHeight,
                    child: Stack(
                      children: [
                        SizedBox(
                            width: MediaQuery.of(context).size.width,
                            child: FittedBox(
                                fit: BoxFit.cover, 
                                child: Image.asset(image!))),
                        const FadeToBlackFilter(),
                        Align(
                          alignment: Alignment.bottomLeft,
                          child: Padding(
                            padding: comfortable,
                            child: Text(
                              title,
                              overflow: TextOverflow.ellipsis,
                              style:
                                  pageTitle(context).copyWith(color: Colors.white),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              })
            : PageTitle(title);
      }
    }
    

    显示此小部件会使应用程序对鼠标事件没有响应。据我所见,小部件显示正确,应用程序仍在更新(例如,调整大小仍会更新小部件)。当我检查调试控制台时,我会看到以下内容:

    ════════ Exception caught by rendering library ═════════════════════════════════
    'package:flutter/src/rendering/box.dart': Failed assertion: line 327 pos 12: 'width > 0.0': is not true.
    The relevant error-causing widget was:
    ════════════════════════════════════════════════════════════════════════════════
    
    ════════ Exception caught by rendering library ═════════════════════════════════
    RenderBox was not laid out: RenderFittedBox#abf19 relayoutBoundary=up22 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    'package:flutter/src/rendering/box.dart':
    Failed assertion: line 2165 pos 12: 'hasSize'
    The relevant error-causing widget was:
    ════════════════════════════════════════════════════════════════════════════════
    ════════ Exception caught by scheduler library ═════════════════════════════════
    'package:flutter/src/rendering/mouse_tracker.dart': Failed assertion: line 200 pos 12: '!_debugDuringDeviceUpdate': is not true.
    ════════════════════════════════════════════════════════════════════════════════
    

    我不知道罪魁祸首是什么。

    我已经尝试过将小部件封装在大小范围内,包括 Expanded() (这使得整件事根本没有呈现出来), SizedBox() 具有定义的宽度和高度(也不渲染),并添加 DebugBorder() (一个带有红色边框的容器)来查看小部件的边框在哪里(正确地延伸到屏幕的宽度和有限的高度)。然而,小部件似乎没有指定的高度(即不是400,我没有覆盖它)。

    1 回复  |  直到 11 月前
        1
  •  1
  •   Franklin Diaz    11 月前

    第一个和第二个错误与没有设置SizedBox的高度有关。虽然错误显示宽度,但这是因为它首先检查宽度,此时宽度和高度都变为0。如果在更正了这一点之后,您看到了第三个错误,我相信它与不在这里的另一段代码有关。

    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Material App',
          home: Scaffold(
            appBar: AppBar(
              title: const Text('Material App Bar'),
            ),
            body: const HeroBanner(
              title: "Hero Banner",
              image: "assets/images/hero.png",
            ),
          ),
        );
      }
    }
    
    class HeroBanner extends StatelessWidget {
      final String? image;
      final String title;
      final double maxHeight;
    
      const HeroBanner(
          {super.key, this.image, this.title = "", this.maxHeight = 100});
    
      @override
      Widget build(BuildContext context) {
        return image != null
            ? LayoutBuilder(builder: (context, constraints) {
                return ClipRect(
                  clipBehavior: Clip.hardEdge,
                  child: SizedBox(
                    height: maxHeight,
                    child: Stack(
                      children: [
                        SizedBox(
                            width: MediaQuery.of(context).size.width,
                            height: maxHeight,  <----------------add height here
                            child: FittedBox(
                                fit: BoxFit.cover, child: Image.asset(image!))),
                        Align(
                          alignment: Alignment.bottomLeft,
                          child: Padding(
                            padding: comfortable,
                            child: Center(
                              child: Text(
                                title,
                                overflow: TextOverflow.ellipsis,
                                style: const TextStyle(
                                    color: Colors.blue, fontSize: 24),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              })
            : PageTitle(title);
      }
    }
    
    var comfortable = const EdgeInsets.all(16);
    
    class PageTitle extends StatelessWidget {
      const PageTitle(this.title, {super.key});
    
      final String title;
    
      @override
      Widget build(BuildContext context) {
        return Text(
          title,
        );
      }
    }