Looking for Flutter Listview with horizontal scroll and Row Property of space between(automatically adjust items with equal spaces) if the item count is less(can fit in on the screen) and slide if the item count is more
Solved by creating keys for each element in the List, then calculating it size in runtime.
If the size of all the elements together is more than the Screen Width, We can have a Row, otherwise, we need to use ListView
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double elementsWidth;
List paymentMethodsList;
@override
void initState() {
paymentMethodsList = [
{
'paymentName': 'UPI Transfer',
"key": GlobalKey(),
},
{
'paymentName': 'NEFT Transfer',
"key": GlobalKey(),
},
{
'paymentName': 'IMPS Transfer',
"key": GlobalKey(),
},
{
'paymentName': 'RTGS Transfer',
"key": GlobalKey(),
},
{
'paymentName': 'UPI Collect',
"key": GlobalKey(),
},
];
super.initState();
}
void postFrameCallback(_) {
double widthOfElements = 0;
int numberOfElementsParsed = 0;
for (int i = 0; i < paymentMethodsList.length; i++) {
var context = paymentMethodsList[i]['key'].currentContext;
if (context == null) return;
numberOfElementsParsed++;
widthOfElements += context.size.width;
}
if (numberOfElementsParsed == paymentMethodsList.length) {
setState(() {
elementsWidth = 100 + widthOfElements;
print(elementsWidth);
});
}
// if (oldSize == newSize) return;
// oldSize = newSize;
// widget.onChange(newSize);
}
@override
Widget build(BuildContext context) {
SchedulerBinding.instance.addPostFrameCallback(postFrameCallback);
return Scaffold(
backgroundColor: Colors.black,
// appBar: buildAppBar(),
body: buildPage(),
);
}
buildPage() => Column(
children: [
SizedBox(
height: 25,
),
buildPaymentListWidget(),
// SizedBox(
// height: 20,
// ),
],
);
Container buildPaymentListWidget() {
return Container(
height: 90,
padding: EdgeInsets.only(left: 20, right: 20),
child: elementsWidth != null &&
elementsWidth < MediaQuery.of(context).size.width
? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (var i = 0; i < paymentMethodsList.length; i++)
buildPaymentItemWidget(i)
],
)
: ListView.separated(
shrinkWrap: false,
scrollDirection: Axis.horizontal,
separatorBuilder: (context, index) => SizedBox(
width: 15,
),
itemBuilder: (context, index) {
return buildPaymentItemWidget(index);
},
itemCount: paymentMethodsList.length,
),
);
}
Container buildPaymentItemWidget(int index) {
return Container(
key: paymentMethodsList[index]['key'],
child: Text(
paymentMethodsList[index]['paymentName'],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12, fontWeight: FontWeight.w400, color: Colors.white),
),
);
}
}