-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
flutter/packages
#5916Closed
Copy link
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.p: two_dimensional_scrollablesIssues pertaining to the two_dimensional_scrollables packageIssues pertaining to the two_dimensional_scrollables packageteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework teamwaiting for PR to land (fixed)A fix is in flightA fix is in flight
Description
Tweaking the example code in the package can reproduce. Found while working on merged cells. It looks like in reverse, the rect for the TableSpanDecoration is not computed correctly.
// 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/gestures.dart';
import 'package:flutter/material.dart';
import 'package:two_dimensional_scrollables/two_dimensional_scrollables.dart';
// Print statements are only for illustrative purposes, not recommended for
// production applications.
// ignore_for_file: avoid_print
void main() {
runApp(const TableExampleApp());
}
/// A sample application that utilizes the TableView API.
class TableExampleApp extends StatelessWidget {
/// Creates an instance of the TableView example app.
const TableExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Table Example',
theme: ThemeData(
useMaterial3: true,
),
home: const TableExample(),
);
}
}
/// The class containing the TableView for the sample application.
class TableExample extends StatefulWidget {
/// Creates a screen that demonstrates the TableView widget.
const TableExample({super.key});
@override
State<TableExample> createState() => _TableExampleState();
}
class _TableExampleState extends State<TableExample> {
late final ScrollController _verticalController = ScrollController();
int _rowCount = 20;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Table Example'),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: TableView.builder(
verticalDetails:
ScrollableDetails.vertical(controller: _verticalController, reverse: true,),
horizontalDetails: ScrollableDetails.horizontal(reverse: true),
cellBuilder: _buildCell,
columnCount: 20,
columnBuilder: _buildColumnSpan,
rowCount: _rowCount,
rowBuilder: _buildRowSpan,
),
),
persistentFooterButtons: <Widget>[
TextButton(
onPressed: () {
_verticalController.jumpTo(0);
},
child: const Text('Jump to Top'),
),
TextButton(
onPressed: () {
_verticalController
.jumpTo(_verticalController.position.maxScrollExtent);
},
child: const Text('Jump to Bottom'),
),
TextButton(
onPressed: () {
setState(() {
_rowCount += 10;
});
},
child: const Text('Add 10 Rows'),
),
],
);
}
Widget _buildCell(BuildContext context, TableVicinity vicinity) {
return Center(
child: Text('Tile c: ${vicinity.column}, r: ${vicinity.row}'),
);
}
TableSpan _buildColumnSpan(int index) {
final TableSpanDecoration decoration = TableSpanDecoration(
color: Colors.blue[100]!.withOpacity(0.6),
border: const TableSpanBorder(
leading: BorderSide(),
trailing: BorderSide(),
),
);
switch (index % 5) {
case 0:
return TableSpan(
foregroundDecoration: decoration,
extent: const FixedTableSpanExtent(100),
onEnter: (_) => print('Entered column $index'),
recognizerFactories: <Type, GestureRecognizerFactory>{
TapGestureRecognizer:
GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
() => TapGestureRecognizer(),
(TapGestureRecognizer t) =>
t.onTap = () => print('Tap column $index'),
),
},
);
case 1:
return TableSpan(
foregroundDecoration: decoration,
extent: const FractionalTableSpanExtent(0.5),
onEnter: (_) => print('Entered column $index'),
cursor: SystemMouseCursors.contextMenu,
);
case 2:
return TableSpan(
foregroundDecoration: decoration,
extent: const FixedTableSpanExtent(120),
onEnter: (_) => print('Entered column $index'),
);
case 3:
return TableSpan(
foregroundDecoration: decoration,
extent: const FixedTableSpanExtent(145),
onEnter: (_) => print('Entered column $index'),
);
case 4:
return TableSpan(
foregroundDecoration: decoration,
extent: const FixedTableSpanExtent(200),
onEnter: (_) => print('Entered column $index'),
);
}
throw AssertionError(
'This should be unreachable, as every index is accounted for in the switch clauses.');
}
TableSpan _buildRowSpan(int index) {
final TableSpanDecoration decoration = TableSpanDecoration(
color: Colors.purple[100]!.withOpacity(0.6),
border: const TableSpanBorder(
leading: BorderSide(),
trailing: BorderSide(),
),
);
switch (index % 3) {
case 0:
return TableSpan(
backgroundDecoration: decoration,
extent: const FixedTableSpanExtent(50),
recognizerFactories: <Type, GestureRecognizerFactory>{
TapGestureRecognizer:
GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
() => TapGestureRecognizer(),
(TapGestureRecognizer t) =>
t.onTap = () => print('Tap row $index'),
),
},
);
case 1:
return TableSpan(
backgroundDecoration: decoration,
extent: const FixedTableSpanExtent(65),
cursor: SystemMouseCursors.click,
);
case 2:
return TableSpan(
backgroundDecoration: decoration,
extent: const FractionalTableSpanExtent(0.15),
);
}
throw AssertionError(
'This should be unreachable, as every index is accounted for in the switch clauses.');
}
}
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.p: two_dimensional_scrollablesIssues pertaining to the two_dimensional_scrollables packageIssues pertaining to the two_dimensional_scrollables packageteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework teamwaiting for PR to land (fixed)A fix is in flightA fix is in flight
Type
Projects
Status
Done
