Как получить виджет локальной позиции своего родительского виджета во Флаттере - PullRequest
0 голосов
/ 15 марта 2020

У меня есть виджет Zoom, в котором CustomPaint с GridView.builder. Есть несколько GridTile внутри GridView в соответствии с вложенной переменной List. GridTile покажет значок, если String в List пусто, и покажет сетевое изображение, если оно не пустое. Я хочу получить изображение Offset при нажатии в соответствии с Container x и y выше GridView. Таким образом, значение Offset никогда не изменится, даже если Container увеличить, уменьшить или перетащить на тот же самый виджет Image, который коснулся.

List<List<String>> _gridState = [
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', 'a', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', 'a', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
      ];

GridView.builder * x и y рассчитывать на основе вложенного List в качестве руководства.

Zoom(
     doubleTapZoom: false,
     backgroundColor: Colors.white,
     width: 2250,
     height: 3000,
     initZoom: 0.3,
     zoomSensibility: 3,
     child: CustomPaint(
     painter: LinePainter(paths: _path),
     child: Container(
        child: Center(
           child: GridView.builder(
               gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: _gridState.length,),
               itemBuilder: _buildGridItem,
               itemCount: _gridState.length * _gridState[0].length,
               scrollDirection: Axis.horizontal,
              ),
      ),
    ),
  ),
),

Построить GridTile в соответствии со значением вложенного списка. Отображать значок, если строка пуста, и изображение, если не пустое.

Widget _buildGridItem(BuildContext context, int index) {
    int gridStateLength = _gridState.length;
    int x, y = 0;
    x = (index % gridStateLength);
    y = (index / gridStateLength).floor();

    GlobalKey imageGK = new GlobalKey();

    return GridTile(
      child: Container(
        child: DottedBorder(
          dashPattern: [10, 20],
          strokeWidth: 10,
          color: Color.fromRGBO(184, 184, 184, 0.6),
          child: Center(
              child: _gridState[x][y].isEmpty
                  ? Icon(
                        Icons.add_circle_outline,
                        size: 100,
                        color: Theme.themeData.accentColor,
                      )
                  : GestureDetector(
                      key: imageGK,
                      onTap: () {
                         //current method to get the offset
                         RenderBox _box = imageGK.currentContext.findRenderObject();
                         Offset offset = _box.localToGlobal(Offset.zero);
                         print("offset ontap: $offset");

                         //with above function, the result is not the correct position
                         //and inconsistent whenever the `Container` is zoomed in,
                         //out or dragged. Sometime the value is negative.
                      },
                      child: Image.network(_imageURL, fit: BoxFit.cover),),
        ),
      ),
    );
  }

Я пробовал метод globalToLocal, результат тот же. Также попытался использовать детали, предоставленные onTapDown в GestureDetector, он возвращает локальный Offset внутри изображения, поэтому линия, проведенная в верхнем левом углу Container.

Я хочу провести линию между GridTile с изображением CustomPainter. Линия будет нарисована на виджете Container, поэтому смещение должно соответствовать Container пикселю, а не экранному пикселю. При использовании текущего метода результат для левого изображения равен Offset(0.7, 306.4), а для правого Offset(206.7, 306.4) строка должна соответствовать изображению.

Current result

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...