// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:two_dimensional_scrollables/two_dimensional_scrollables.dart';
void main() {
runApp(const TableExampleApp());
}
class TableExampleApp extends StatelessWidget {
const TableExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Table Example',
theme: ThemeData(
useMaterial3: true,
),
home: const TableExample(),
);
}
}
class TableExample extends StatefulWidget {
const TableExample({super.key});
@override
State<TableExample> createState() => _TableExampleState();
}
class _TableExampleState extends State<TableExample> {
final StringBuffer _sb = StringBuffer('Row Activity Log:\n');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Table Example'),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: TableView.builder(
cellBuilder: _buildCell,
columnCount: 10,
columnBuilder: _buildColumnSpan,
rowCount: 10,
rowBuilder: _buildRowSpan,
),
),
Expanded(
child: SingleChildScrollView(
child: Text(_sb.toString()),
),
),
],
),
),
);
}
TableViewCell _buildCell(BuildContext context, TableVicinity vicinity) {
return TableViewCell(
child: Center(
child: Text('Tile c: ${vicinity.column}, r: ${vicinity.row}'),
),
);
}
TableSpan _buildColumnSpan(int index) {
const TableSpanDecoration decoration = TableSpanDecoration(
border: TableSpanBorder(
trailing: BorderSide(),
),
);
return const TableSpan(
foregroundDecoration: decoration,
extent: FixedTableSpanExtent(100),
);
}
TableSpan _buildRowSpan(int index) {
final TableSpanDecoration decoration = TableSpanDecoration(
color: index.isEven ? Colors.purple[100] : null,
border: const TableSpanBorder(
trailing: BorderSide(
width: 3,
),
),
);
return TableSpan(
backgroundDecoration: decoration,
extent: const FixedTableSpanExtent(50),
onEnter: (_) => setState(() => _sb.writeln('onEnter row $index')),
onExit: (_) => _sb.writeln('onExit row $index'),
);
}
}
What package does this bug report belong to?
two_dimensional_scrollables
What target platforms are you seeing this bug on?
Web, Windows
Have you already upgraded your packages?
Yes
Dependency versions
pubspec.lock
Steps to reproduce
Expected results
onEnteronly gets called when the pointer moves from outside the region encompased by the row Span to within the region encompased by the row span.onExitonly gets called when the pointer moves from inside the region encompased by the row Span to outside the region encompased by the row span.Actual results
Every time
setStateis called withinonEnter,onExitgets called followed byonEnteragain.This results in a constant loop.
This is occuring even though the pointer is not moving and the call to
setStateis not updating any variable that theTableViewwidget depends upon.Code sample
Code sample
Screenshots or Videos
Screenshots / Video demonstration
[Upload media here]
Logs
Logs
[Paste your logs here]Flutter Doctor output
Doctor output