Is there a simple way to add scrolling to row when there is no room left for space between its items?
I.e. option1 and option2 together in the code above. Trying to apply width constraints to row (or scrollview) in case of option2 didn’t have the necessary effect. Any hints?
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart' show PointerDeviceKind;
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) =>
MaterialApp(home: const HomePage(), scrollBehavior: ScrollBehavior(), debugShowCheckedModeBanner: false);
}
class ScrollBehavior extends MaterialScrollBehavior {
@override
Set<PointerDeviceKind> get dragDevices => { PointerDeviceKind.touch, PointerDeviceKind.mouse };
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) => LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) =>
Scaffold(
appBar: AppBar(title: const Text('scroll test')),
body: Column(children: [
// Option1: space between, no scrollable
_row,
// Option2: scrollable, no space between
SingleChildScrollView(scrollDirection: Axis.horizontal, child: _row),
]),
)
);
}
get _row => Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Container(color: Colors.green, child: Text("${'l' * 30}")),
Container(color: Colors.red, child: Text("${'r' * 30}")),
]);
2
Answers
You can wrap the
Row
withLayoutBuilder
and make the decision by comparing the available width (by using itsconstraints
value) to the space needed by yourRow
(follow steps on this answer).I’ve been using a widget I like to call Expandify for a while now and decided to clean it up and publish it to pub.dev as expandify, which should do what you need. This is fairly cpu-itensive as it requires a separate layout pass so don’t use it willy-nilly wherever.
What it does is use a LayoutBuilder, a ConstrainedBox, and a IntrinsicHeight widget to first calculate the amount of space available and then make the inner part of the scrollable take up that much space.
Using it looks like this:
Note that if you don’t specify the mainAxisAlignment, the boxes will just stay at the left side. Also, using one or two in a page shouldn’t cause any issues, but if you have a vertical list with a bunch of rows each doing this you might want to think of re-designing or coming up with a different solution as it could cause performance or cpu issues. Note that there are certain situations where it won’t work, for example inside a scrollable of the same direction.
The paired down code for Expandify looks like this: