简体   繁体   中英

Flutter ListView with Row Property of space between

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),
      ),
    );
  }
}

You can use the code with Scroll Direction for wrap you can use Expanded.

ListView.builder(
              scrollDirection: Axis.horizontal,
                itemCount: numbers.length,
               itemBuilder: (context, index) {
                  return Container(
                    width: MediaQuery.of(context).size.width * 0.6,
                    child: Card(
                      color: Colors.blue,
                      child: Container(
                        child: Center(child: "text", style: TextStyle(color: Colors.white, fontSize: 36.0),)),
                      ),
                    ),
                  );
            }),

For equal separator user ListView.separator like this

ListView.separated(
  scrollDirection: Axis.horizontal,
  separatorBuilder: (context, index) => Divider(
        color: Colors.black,
      ),
  itemCount: 20,
  itemBuilder: (context, index) => Padding(
        padding: EdgeInsets.all(8.0),
        child: Center(child: Text("Index $index")),
      ),
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM