我正在制作一款Ffltter的绘图应用程序.当我把它放在只有家的脚手架上时,我可以正常地画一条线.但问题是,当我添加一个AppBar时,行从顶部向下偏移,它不是我在屏幕上touch 的位置,它与App bar的高度一样向下移动.

这是我的代码.

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

  @override
  State<HiraganaWriting> createState() => _HiraganaWritingState();
}

class _HiraganaWritingState extends State<HiraganaWriting> {
  final GlobalKey _globalKey = GlobalKey();
  List<DrawnLine> lines = <DrawnLine>[];
  DrawnLine line = DrawnLine([Offset(50, 50)], Colors.black, 5.0);
  Color selectedColor = Colors.black;
  double selectedWidth = 5.0;

  StreamController<List<DrawnLine>> linesStreamController = StreamController<List<DrawnLine>>.broadcast();
  StreamController<DrawnLine> currentLineStreamController = StreamController<DrawnLine>.broadcast();

  String picName = "Hi";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AppBar"),
      ),
      body: Container(
        child: Stack(
          children: [
            buildAllPaths(context),
            buildCurrentPath(context),
          ],
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.arrow_back), label: ""),
          BottomNavigationBarItem(icon: Icon(Icons.arrow_back), label: ""),
          BottomNavigationBarItem(icon: Icon(Icons.arrow_back), label: ""),
          BottomNavigationBarItem(icon: Icon(Icons.arrow_back), label: ""),
        ],
      ),
    );
  }

  Widget buildAllPaths(BuildContext context) {
    return RepaintBoundary(
      key: _globalKey,
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        color: Colors.transparent,
        padding: EdgeInsets.all(4),
        alignment: Alignment.topLeft,
        child: StreamBuilder<List<DrawnLine>>(
          stream: linesStreamController.stream,
          builder: (context, snapshot) {
            return CustomPaint(
              painter: Sketcher(
                lines: lines,
              ),
            );
          },
        ),
      ),
    );
  }

  Widget buildCurrentPath(BuildContext context) {
    return GestureDetector(
      onPanStart: onPanStart,
      onPanUpdate: onPanUpdate,
      onPanEnd: onPanEnd,
      child: RepaintBoundary(
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          padding: EdgeInsets.all(4),
          color: Colors.transparent,
          alignment: Alignment.topLeft,
          child: StreamBuilder<DrawnLine>(
            stream: currentLineStreamController.stream,
            builder: (context, snapshot) {
              return CustomPaint(
                painter: Sketcher(
                  lines: [line],
                ),
              );
            },
          ),
        ),
      ),
    );
  }

  void onPanStart(DragStartDetails details) {
    RenderBox? box = context.findRenderObject() as RenderBox?;
    Offset point = box!.globalToLocal(details.globalPosition);
    line = DrawnLine([point], selectedColor, selectedWidth);
  }

  void onPanUpdate(DragUpdateDetails details) {
    RenderBox? box = context.findRenderObject() as RenderBox?;
    Offset point = box!.globalToLocal(details.globalPosition);

    List<Offset> path = List.from(line.path)..add(point);
    line = DrawnLine(path, selectedColor, selectedWidth);
    currentLineStreamController.add(line);
  }

  void onPanEnd(DragEndDetails details) {
    lines = List.from(lines)..add(line);

    linesStreamController.add(lines);
  }
}

enter image description here

我试着换了衬垫,或者把Container放进了一个大小的盒子里,...但它的工作方式有误

推荐答案

不要使用HiraganaWriting个Widget内部的脚手架,这个Widget是应用程序的绘画部分,只需将此Widget与scaffold分开.

HiraganaWriting:

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

  @override
  State<HiraganaWriting> createState() => _HiraganaWritingState();
}

class _HiraganaWritingState extends State<HiraganaWriting> {
  final GlobalKey _globalKey = GlobalKey();
  List<DrawnLine> lines = <DrawnLine>[];
  DrawnLine line = DrawnLine([Offset(50, 50)], Colors.black, 5.0);
  Color selectedColor = Colors.black;
  double selectedWidth = 5.0;

  StreamController<List<DrawnLine>> linesStreamController =
      StreamController<List<DrawnLine>>.broadcast();
  StreamController<DrawnLine> currentLineStreamController =
      StreamController<DrawnLine>.broadcast();

  String picName = "Hi";

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        buildAllPaths(context),
        buildCurrentPath(context),
      ],
    );
  }

  Widget buildAllPaths(BuildContext context) {
    return RepaintBoundary(
      key: _globalKey,
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        color: Colors.transparent,
        padding: EdgeInsets.all(4),
        alignment: Alignment.topLeft,
        child: StreamBuilder<List<DrawnLine>>(
          stream: linesStreamController.stream,
          builder: (context, snapshot) {
            return CustomPaint(
              painter: Sketcher(
                lines: lines,
              ),
            );
          },
        ),
      ),
    );
  }

  Widget buildCurrentPath(BuildContext context) {
    return GestureDetector(
      onPanStart: onPanStart,
      onPanUpdate: onPanUpdate,
      onPanEnd: onPanEnd,
      child: RepaintBoundary(
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          padding: EdgeInsets.all(4),
          color: Colors.transparent,
          alignment: Alignment.topLeft,
          child: StreamBuilder<DrawnLine>(
            stream: currentLineStreamController.stream,
            builder: (context, snapshot) {
              return CustomPaint(
                painter: Sketcher(
                  lines: [line],
                ),
              );
            },
          ),
        ),
      ),
    );
  }

  void onPanStart(DragStartDetails details) {
    RenderBox? box = context.findRenderObject() as RenderBox?;
    Offset point = box!.globalToLocal(details.globalPosition);
    line = DrawnLine([point], selectedColor, selectedWidth);
  }

  void onPanUpdate(DragUpdateDetails details) {
    RenderBox? box = context.findRenderObject() as RenderBox?;
    Offset point = box!.globalToLocal(details.globalPosition);

    List<Offset> path = List.from(line.path)..add(point);
    line = DrawnLine(path, selectedColor, selectedWidth);
    currentLineStreamController.add(line);
  }

  void onPanEnd(DragEndDetails details) {
    lines = List.from(lines)..add(line);

    linesStreamController.add(lines);
  }
}

然后在您的页面小工具中使用它,如下所示:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("AppBar"),
        ),
        body: const HiraganaWriting());
  }
}

Flutter相关问答推荐

为什么Flutter InAppWebView中的DatePicker看起来很旧?

来自FutureProvider的数据只打印两个不同的变量,它们对一个实例只有一次相同的值,为什么?

相同的Flutter 代码库,但Firebase登录适用于Web应用程序,但无法登录iOS应用程序

如何知道当前屏幕是否处于抖动状态?

如何在抖动中预加载一条路由,或者即使在屏幕外也保持加载小工具?

为什么在setState之后Ffltter Pageview重置为第0页

如何让经过Firebase身份验证的用户能够将Zip文件上载到Firebase云存储?

我怎样才能在Ffltter中显示html布局链接?

使小部件处于有状态状态会导致hasSize异常

Flutter:如何设置 PersistentFooterButtons 背景?

模块是使用不兼容的 kotlin 版本编译的.其元数据的二进制版本是1.8.0,预期版本是1.6

Flutter:如何从运行时创建的列表中访问单个子部件的值

如何在 flutter 中使用带有有效负载数据的重定向来执行 firebase 推送通知.?

如何格式化网址?

我可以定义一次 sharedPreferences 并在需要数据显示到 flutter 应用程序时调用它吗?

在 flutter 的另一个类中使用变量值

我怎样才能一次只选中一个复选框?

type '({bool growable}) => List' 不是类型转换中类型 'List' 的子类型

Flutter:font_awesome_icon pro 版报错?如何设置 font_awesome 克隆仓库的路径?

有没有办法帮助我修复类型 null 不是 Map 类型的子类型?