Last active
March 6, 2025 16:41
-
-
Save hectorAguero/118b2ea4244b997fcdaa18b78eded466 to your computer and use it in GitHub Desktop.
TableRow with Leading and Trailing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
void main() => runApp(const MyApp()); | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) => MaterialApp( | |
title: 'Material App', | |
home: Scaffold( | |
appBar: AppBar(title: const Text('Material App Bar')), | |
body: Center( | |
child: SizedBox( | |
width: 200, | |
child: TableRow( | |
//leadingText: 'Time, Meeting and Reservations', | |
leadingText: '05:00AM - 15:00PM', | |
trailingText: '05:00AM - 15:00PM05:00AM - 15:00PM', | |
maxLines: 2, | |
textLayout: TextLayoutPriority.trailingPriority, | |
), | |
), | |
), | |
), | |
); | |
} | |
enum TextLayoutPriority { | |
equalDistribution, // Allocate equal space (50-50). | |
leadingPriority, // Prioritize the leading text. | |
trailingPriority, // Prioritize the trailing text. | |
longerTextPriority, // Prioritize the text that is longer. | |
} | |
class TableRow extends StatelessWidget { | |
const TableRow({ | |
super.key, | |
this.leadingText, | |
this.trailingText, | |
this.maxLines = 2, | |
this.textLayout = TextLayoutPriority.trailingPriority, | |
}); | |
final String? leadingText; | |
final String? trailingText; | |
final int maxLines; | |
final TextLayoutPriority textLayout; | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
color: Colors.yellow, | |
child: Row( | |
mainAxisAlignment: _validateAlignment(), | |
children: [ | |
if ((leadingText ?? '').isNotEmpty) | |
_MyText( | |
leadingText!, | |
isExpanded: switch (textLayout) { | |
TextLayoutPriority.equalDistribution => true, | |
TextLayoutPriority.leadingPriority => true, | |
TextLayoutPriority.trailingPriority => false, | |
TextLayoutPriority.longerTextPriority => isLongerText( | |
leadingText, | |
trailingText, | |
), | |
}, | |
maxLines: maxLines, | |
), | |
if ((leadingText ?? '').isNotEmpty && (trailingText ?? '').isNotEmpty) | |
ColoredBox( | |
color: Colors.green, | |
child: SizedBox(width: 16, height: 20), | |
), | |
if ((trailingText ?? '').isNotEmpty) | |
_MyText( | |
trailingText!, | |
isExpanded: switch (textLayout) { | |
TextLayoutPriority.equalDistribution => true, | |
TextLayoutPriority.leadingPriority => false, | |
TextLayoutPriority.trailingPriority => true, | |
TextLayoutPriority.longerTextPriority => isLongerText( | |
leadingText, | |
trailingText, | |
), | |
}, | |
maxLines: maxLines, | |
), | |
], | |
), | |
); | |
} | |
bool isLongerText(String? text, String? longerText) { | |
if ((text?.length ?? 0) > (longerText?.length ?? 0)) return true; | |
return false; | |
} | |
MainAxisAlignment _validateAlignment() { | |
//if ((trailingText ?? '').isEmpty) return MainAxisAlignment.start; | |
if ((leadingText ?? '').isEmpty) return MainAxisAlignment.end; | |
return MainAxisAlignment.start; | |
} | |
} | |
class _MyText extends StatelessWidget { | |
const _MyText(this.text, {required this.isExpanded, required this.maxLines}); | |
final String text; | |
final bool isExpanded; | |
final int maxLines; | |
@override | |
Widget build(BuildContext context) { | |
if (isExpanded) { | |
// How to make this work only when is needed "Overflow" | |
// but avoid get half the space if not, like with a short word "Time" | |
return Flexible( | |
flex: 1, | |
child: ColoredBox( | |
color: Colors.red, | |
child: Text( | |
text, | |
maxLines: maxLines, | |
overflow: TextOverflow.ellipsis, | |
), | |
), | |
); | |
} | |
return Expanded( | |
child: ColoredBox( | |
color: Colors.blue, | |
child: Text(text, maxLines: maxLines, overflow: TextOverflow.ellipsis), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment