I want align the following nested list in such a way that black line should be horizontally center of the green box (parent list) i cant add any padding or extra space or positioned or increase the red column width
please note black line is for reference the line actually not part of the code
dartpad ready code here
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Horizontal List of Vertical Lists')),
body: ParentLayout(),
),
);
}
}
class ParentLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
// Header content (Green Box at the top)
Container(
height: 100,
width: 200,
color: Colors.green[100],
child: Center(child: Text("Parent ListView Content Above")),
),
// Horizontal layout with dividing line centered to green boxes
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Blue List
_generateBlueList(),
// Dividing line
// Red List
_generateRedList(),
],
),
),
// Footer content (Green Box at the bottom)
Container(
height: 100,
width: 200,
color: Colors.green[100],
child: Center(child: Text("Parent ListView Content Below")),
),
],
);
}
// Generate blue list with varying sizes
Widget _generateBlueList() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
5,
(innerIndex) => Container(
height: 40 + (innerIndex * 25), // Varying height
width: 80 + (innerIndex * 40), // Varying width
color: Colors.blue[100 * (innerIndex + 1)],
child: Center(
child: Text(
'Blue $innerIndex',
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
// Generate red list with fixed sizes
Widget _generateRedList() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
5,
(innerIndex) => Container(
height: 60, // Fixed height
width: 100, // Fixed width
color: Colors.red[100 * (innerIndex + 1)],
child: Center(
child: Text(
'Red $innerIndex',
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
}
I did bit of math to find necessary x axis translate, and achieved it.
to make the other neighbouring widget respect the translated widget position, im adding padding to entire parent column. And its not wasting the space, because transformed widget is laying there.
[![import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Dynamic Horizontal List')),
body: ParentLayout(),
),
);
}
}
class ParentLayout extends StatefulWidget {
@override
_ParentLayoutState createState() => _ParentLayoutState();
}
class _ParentLayoutState extends State<ParentLayout> {
final GlobalKey _blueKey = GlobalKey();
final GlobalKey _redKey = GlobalKey();
double _blueListWidth = 0;
double _redListWidth = 0;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _updateWidths());
}
void _updateWidths() {
final blueRenderBox = _blueKey.currentContext?.findRenderObject() as RenderBox?;
final redRenderBox = _redKey.currentContext?.findRenderObject() as RenderBox?;
if (blueRenderBox != null && redRenderBox != null) {
final double newBlueListWidth = blueRenderBox.size.width;
final double newRedListWidth = redRenderBox.size.width;
// Update state only if widths have changed
if (_blueListWidth != newBlueListWidth || _redListWidth != newRedListWidth) {
setState(() {
_blueListWidth = newBlueListWidth;
_redListWidth = newRedListWidth;
});
}
}
}
@override
Widget build(BuildContext context) {
// Calculate the translation for the entire row based on which list is wider
final double rowTranslation = (_blueListWidth > _redListWidth)
? -((_blueListWidth - _redListWidth) / 2) // Translate left if blue is wider
: ((_redListWidth - _blueListWidth) / 2); // Translate right if red is wider
// Calculate dynamic padding for the parent list view
final EdgeInsets parentPadding = EdgeInsets.only(
left: rowTranslation < 0 ? rowTranslation.abs() : 0, // Padding on left
right: rowTranslation > 0 ? rowTranslation.abs() : 0, // Padding on right
);
return Padding(
padding: parentPadding, // Apply dynamic padding
child: Column(
children: \[
// Header content (Green Box at the top)
Container(
height: 100,
width: 200,
color: Colors.green\[100\],
child: Center(child: Text("Parent ListView Content Above")),
),
// Horizontal layout with dividing line centered to green boxes
IntrinsicHeight(
child: Transform.translate(
offset: Offset(rowTranslation, 0), // Translate based on the width difference
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, // Align to the top of the Row
children: \[
// Blue List wrapped in IntrinsicWidth
IntrinsicWidth(
child: Container(
key: _blueKey,
color: Colors.blue.withOpacity(0.2), // Background for visual distinction
child: _generateBlueList(),
),
),
// Divider
Container(
width: 2,
color: Colors.grey,
margin: EdgeInsets.symmetric(horizontal: 8),
),
// Red List wrapped in IntrinsicWidth
IntrinsicWidth(
child: Container(
key: _redKey,
color: Colors.red.withOpacity(0.2), // Background for visual distinction
child: _generateRedList(),
),
),
\],
),
),
),
// Footer content (Green Box at the bottom)
Container(
height: 100,
width: 200,
color: Colors.green\[100\],
child: Center(child: Text("Parent ListView Content Below")),
),
\],
),
);
}
// Generate blue list with varying sizes
Widget _generateBlueList() {
return Column(
mainAxisAlignment: MainAxisAlignment.start, // Align items to the top
children: List.generate(
5,
(innerIndex) => Container(
height: 40 + (innerIndex * 25), // Varying height
width: 80 + (innerIndex * 40), // Varying width
color: Colors.blue\[100 * (innerIndex + 1)\],
child: Center(
child: Text(
'Blue $innerIndex',
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
// Generate red list with fixed sizes
Widget _generateRedList() {
return Column(
mainAxisAlignment: MainAxisAlignment.start, // Align items to the top
children: List.generate(
5,
(innerIndex) => Container(
height: 60, // Fixed height
width: 100, // Fixed width
color: Colors.red\[100 * (innerIndex + 1)\],
child: Center(
child: Text(
'Red $innerIndex',
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
}