创建自定义光标和正确的实现使用定位的小部件

时间:2020-04-18 04:32:27

标签: flutter flutter-web

我有这样的主dart文件树:

Profile
  MaterialApp
    Material
      Stack
        Homepage
        Positioned
          OverlaySizing
        CursorTest

有问题的两个是OverlaySizing和CursorTest小部件。基本功能应该是:首页是底部绘制的小部件,它覆盖整个页面;中间部件是带有OverlaySizing子级的Positioned部件,该子级仅在屏幕的右下方打印MediaQueries,以进行调试;顶部是顶部。 -绘制最多的窗口小部件应该是一个正方形的窗口小部件,无论鼠标在哪里,它都会绘制10x10的正方形。

Main.dart

import 'package:flutter/material.dart';

import 'themes/themes.dart';

import 'debug/sizing.dart';
import 'debug/featureTesting.dart';

import 'dart:html' as html;

import 'pages/homepage.dart';


//  Entry point for app
void main() {
  runApp(Profile());
}

class Profile extends StatelessWidget {

  //  Starting build function that builds whole widget tree.
  //  Starts with Material app to give default text theme and supplies 
  //    custom color theming.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TWB',
      theme: originalTheme(),
      home: Material( //  Must surround the page with a Material widget for Material properties.
        child: Stack(
          children: [
            Homepage(),  //  The Homepage widget that the houses the UI
            Positioned(
              bottom: 5,
              right: 5,
              child: OverlaySizing(),  //  Container that prints the MediaQuery info
            ),
            CursorTest(  //  Widget to print a square where the mouse is.
              appContainer: html.window.document.getElementById('app-container'),
            ),
          ],
        ),
      )
    );
  }
}

sizing.dart

import 'package:flutter/material.dart';

//  A wrapping Widget that prints Sizing information overtop
//    a child widget tree using a Stack.

class OverlaySizing extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Column(  
      children: [
        Text(
          'Orientation: ' + MediaQuery.of(context).orientation.toString(),
          style: Theme.of(context).textTheme.overline
        ),
        Text(
          'Size: ' + MediaQuery.of(context).size.toString(),
          style: Theme.of(context).textTheme.overline
        )
      ]
    );
  }
}

testingFeature.dart

import 'package:flutter/material.dart';

//  CursorTest
import 'dart:html' as html;

class CursorTest extends StatefulWidget {

  final html.Element appContainer;

  CursorTest({
    Key key,
    @required this.appContainer,  //  Have to pass the body element to change the cursor for the page
  }): super(key: key);

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

class _CursorTestState extends State<CursorTest> {

  double mouseX;
  double mouseY;

    //  function that sets the state to update the widget location to where the mouse is.
  void _updateMouseLocation(PointerEvent details) {
      //  Uses the body element to disable the graphical cursor to redraw my own.  
    widget.appContainer.style.cursor = 'none';
    setState(() {
      mouseX = details.position.dx;
      mouseY = details.position.dy;
    });
  }

  @override
  Widget build(BuildContext context) {

      //  A Box widget to draw as the cursor rather than use the default cursor.    
    Widget boxCursor = Container(
      width: 10,
      height: 10,
      decoration: BoxDecoration(
        color: Colors.grey,
      )
    );

      //  MouseRegion widget allows to grab the location of the mouse whenever the mouse moves
    return MouseRegion(
      onHover: _updateMouseLocation,
      child: Positioned(  // QUESTION: DOES THIS POSITION WIDGET WORK?
        top: mouseX,
        left: mouseY,
        child: Column(  // Draws the cursor and text with location of mouse.
          children: [
            boxCursor,
            Text(
              '${mouseX.toStringAsFixed(2)}, ${mouseY.toStringAsFixed(2)}',
              style: Theme.of(context).textTheme.overline,
            )
          ]
        ),
      )
    );
  }
}

在不使用CursorText小部件的情况下运行代码时,主页会正确显示,并且OverlaySizing小部件会准确显示页面的大小并在调整页面大小时正确更新。

当我添加CursorTest小部件时,在调整页面大小时,OverlaySizing小部件不会更新,并且在默认光标仍在的情况下不会重绘光标。我似乎无法弄清楚为什么会这样。我感觉这与Stack and Positioned有关。有没有人可以弄清楚这里出了什么问题?

我的理解是,堆栈采用父级的大小,即Material,即整个页面的大小。主页将是堆栈的大小,因为它没有定义自己的大小。 overlaySizing是其中的Text对象的大小,位于堆栈的右下角。 CursorText的大小应与boxCursor定义的大小相同,并位于堆栈中。这种逻辑在哪里失败?

我了解到Flutter Web不稳定,并且存在一些古怪之处,但是由于没有有关光标自定义的官方文档,因此我不得不找出解决方案,而我尝试过的其中一些解决方案使整个屏幕空白,或导致错误。这个解决方案是我最近提出的。感谢您的帮助!

0 个答案:

没有答案