Vertical alignment of a list inside a FutureBuilder

73 Views Asked by At

I have the following screen which displays a list of categories retrieved from a REST API. My MainCategoryProvider takes care of it.

I have an AppBar, a tip text (my custom tipText widget), the list of categories and a custom BottomBar with an action button and the app menu

import 'package:choooze_app/models/main_category_model.dart';
import 'package:choooze_app/providers/main_category_provider.dart';
import 'package:choooze_app/widgets/bottom_bar.dart';
import 'package:choooze_app/widgets/tip_text.dart';
import 'package:choooze_app/widgets/title.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:choooze_app/widgets/action_button.dart';

class MainCategoryListScreen extends StatelessWidget {
  final _mainCategoryProvider = Get.find<MainCategoryProvider>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: title(context, titleText: 'maincategory_list_title'.tr),
      body: Padding(
        padding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 16.0),
        child: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              tipText(context, text: 'maincategory_list_tip'.tr),
              Expanded(
                child: FutureBuilder<List<MainCategoryModel>>(
                  future: _mainCategoryProvider.getMainCategories(),
                  builder: (context, snapshot) {
                    if (snapshot.connectionState == ConnectionState.waiting) {
                      return Center(
                        child: CircularProgressIndicator(),
                      );
                    } else if (snapshot.hasError) {
                      return Center(
                        child: Text('Error: ${snapshot.error}'),
                      );
                    } else {
                      final mainCategories = snapshot.data!;
                      return ListView.builder(
                        itemCount: mainCategories.length,
                        itemBuilder: (context, index) {
                          var mainCategory = mainCategories[index];
                          return InkWell(
                            child: Container(
                              padding:
                                  const EdgeInsets.fromLTRB(0, 5.0, 0, 5.0),
                              decoration: index < mainCategories.length - 1
                                  ? BoxDecoration(
                                      border: Border(
                                        bottom: BorderSide(
                                          color: Color(0xffcccccc),
                                        ),
                                      ),
                                    )
                                  : BoxDecoration(),
                              child: Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceBetween,
                                children: [
                                  Text(Get.locale == Locale('en')
                                      ? mainCategory.nameEn
                                      : mainCategory.nameFr),
                                  Text(
                                    !mainCategory.active
                                        ? 'maincategory_detail_inactive'.tr
                                        : '',
                                    style: TextStyle(
                                      color: Color(0xFFD06706),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                            onTap: () {},
                          );
                        },
                      );
                    }
                  },
                ),
              ),
              BottomBar(
                child: actionButton(
                  context,
                  buttonText: 'maincategory_list_actions_new'.tr,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

This gives me the following results => Capture of the screen It looks good, but I would like the list of elements to stick to the bottom of the screen, right above the green button.

How can I achieved that?

I try to play with column settings but without success. If a wrap the ListView.builder inside a Column widget with a MainAxisAlignment.end, I get the followin g error:


════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderViewport#82eda NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
box.dart:1
Failed assertion: line 1966 pos 12: 'hasSize'

The relevant error-causing widget was
ListView
main_category_list_screen.dart:44
════════════════════════════════════════════════════════════════════════════════
```
1

There are 1 best solutions below

2
On

If I understood correctly and you want the list to start from the bottom, then try using MainAxisAlignment.end in the mainAxisAlignment field in Column.

Column(
  ...
  mainAxisAlignment: MainAxisAlignment.end,
  ...
);