У меня есть виджет 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)
строка должна соответствовать изображению.