syncfusion / flutter-examples

This repository contains the Syncfusion Flutter UI widgets examples and the guide to use them.
Other
1.98k stars 775 forks source link

SfDataGrid auto width columns doesn't seem to work as per documentation #655

Closed daveshirman closed 2 years ago

daveshirman commented 2 years ago

Having followed the examples here and thoroughly read the documentation here, I simply don't understand why my columns don't show all their content.

See in this screenshot, but the email and phone number columns are cut off: Screenshot 2022-07-20 at 10 42 11

Things I tried to pay attention to:

Any help to explain why this is happening would be greatly appreciated, thanks.

Page:

import 'package:flutter/material.dart';
import 'package:gt_elite/datasource/athlete_data_source.dart';
import 'package:gt_elite/helpers/colors.dart';
import 'package:gt_elite/helpers/constants.dart';
import 'package:gt_elite/helpers/gt_text_style.dart';
import 'package:gt_elite/models/team.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:easy_localization/easy_localization.dart';

class ManagementAdminScreen extends StatelessWidget {
  final Team team;

  ManagementAdminScreen({@required this.team});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
          color: Colors.white,
          child: SfDataGrid(
            source: AthleteDataSource(
              athletes: team.getAthletesForProfile(Profile.athlete),
            ),
            columnWidthMode: ColumnWidthMode.auto,
            columnWidthCalculationRange: ColumnWidthCalculationRange.allRows,
            frozenColumnsCount: 0,
            columns: [
              _buildColumn('avatar', 'profile.athlete'),
              _buildColumn('email', 'email'),
              _buildColumn('phoneNumber', 'phoneNumber'),
              _buildColumn('birthdate', 'birthdate'),
              _buildColumn('height', 'height'),
            ],
          )),
    );
  }

  GridColumn _buildColumn(String name, String lbl) {
    return GridColumn(
      autoFitPadding: EdgeInsets.symmetric(horizontal: 16.0),
      columnName: name,
      label: Container(
        padding: EdgeInsets.symmetric(horizontal: 16.0),
        alignment: Alignment.centerLeft,
        child: Text(
          lbl.tr(),
          style: GTTextStyle.subtitle2.copyWith(
            color: GTColors.textGrey,
          ),
          softWrap: false,
        ),
      ),
    );
  }
}

AthleteDataSource

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:gt_elite/helpers/gt_text_style.dart';
import 'package:gt_elite/helpers/string.dart';
import 'package:gt_elite/models/athlete.dart';
import 'package:intl/intl.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:url_launcher/url_launcher.dart';

class AthleteDataSource extends DataGridSource {
  final _dateFormatter = DateFormat.yMd();

  AthleteDataSource({List<Athlete> athletes}) {
    dataGridRows = athletes
        .map<DataGridRow>(
          (dataGridRow) => DataGridRow(
            cells: [
              DataGridCell<Athlete>(
                columnName: 'avatar',
                value: dataGridRow,
              ),
              DataGridCell<String>(
                columnName: 'email',
                value: dataGridRow.email,
              ),
              DataGridCell<String>(
                columnName: 'phone',
                value: dataGridRow.phoneNumber,
              ),
              DataGridCell<DateTime>(
                columnName: 'birthdate',
                value: dataGridRow.birthdate,
              ),
              DataGridCell<double>(
                columnName: 'height',
                value: dataGridRow.height,
              ),
            ],
          ),
        )
        .toList();
  }

  List<DataGridRow> dataGridRows = [];

  @override
  List<DataGridRow> get rows => dataGridRows;

  @override
  bool shouldRecalculateColumnWidths() {
    return true;
  }

  void _launchCaller(String url) async {
    final uri = Uri.parse(url);
    if (await canLaunchUrl(uri)) {
      await launchUrl(uri);
    } else {
      throw 'Could not launch $uri';
    }
  }

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      // Avatar cell
      if (dataGridCell.columnName == 'avatar') {
        if (dataGridCell.value.getAvatarUrl() != null) {
          return Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                SizedBox(
                  width: 18,
                ),
                if (dataGridCell.value.getAvatarUrl() != null)
                  Padding(
                    padding: const EdgeInsets.only(right: 8.0),
                    child: Container(
                      width: 30,
                      height: 30,
                      // decoration: getBoxDecoration(),
                      child: ClipOval(
                        child: CachedNetworkImage(
                          height: 30,
                          width: 30,
                          imageUrl: dataGridCell.value.getAvatarUrl(),
                          placeholder: (context, url) =>
                              CircularProgressIndicator(),
                          errorWidget: (context, url, error) =>
                              Icon(Icons.error),
                        ),
                      ),
                    ),
                  ),
                if (dataGridCell.value.getAvatarUrl() == null)
                  SizedBox(
                    width: 30,
                  ),
                Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    FittedBox(
                      fit: BoxFit.scaleDown,
                      child: Text(
                        "${StringHelper.shortName(dataGridCell.value.lastName, nameLimit: 15)}",
                        textAlign: TextAlign.left,
                        style: GTTextStyle.subtitle2,
                      ),
                    ),
                    FittedBox(
                      fit: BoxFit.scaleDown,
                      child: Text(
                        "${StringHelper.shortName(dataGridCell.value.firstName, nameLimit: 15)}",
                        textAlign: TextAlign.left,
                        style: GTTextStyle.body,
                      ),
                    ),
                  ],
                )
              ]);
        }
      }
      if (dataGridCell.columnName == 'birthdate') {
        if (dataGridCell.value == null) return Container();
        return Container(
            alignment: Alignment.centerLeft,
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            child: Text(
              _dateFormatter.format(dataGridCell.value),
              // overflow: TextOverflow.ellipsis,
              style: GTTextStyle.body,
              softWrap: false,
            ));
      }

      if (dataGridCell.columnName == 'phone') {
        if (dataGridCell.value == null) return Container();
        return InkWell(
          onTap: () {
            String phoneNumber = dataGridCell.value;
            phoneNumber = phoneNumber.replaceAll(" ", "").replaceAll(".", "");
            _launchCaller('tel:${phoneNumber}');
          },
          child: Container(
              alignment: Alignment.centerLeft,
              padding: EdgeInsets.symmetric(horizontal: 16.0),
              child: Text(
                dataGridCell.value.toString(),
                // overflow: TextOverflow.ellipsis,
                style: GTTextStyle.body,
                softWrap: false,
              )),
        );
      }

      if (dataGridCell.columnName == 'email') {
        if (dataGridCell.value == null) return Container();
        return InkWell(
          onTap: () {
            String val = dataGridCell.value;
            val = val.replaceAll(" ", "");
            _launchCaller('mailto:${val}');
          },
          child: Container(
              alignment: Alignment.centerLeft,
              // The autoFitPadding and the cell padding value should be same.
              padding: EdgeInsets.symmetric(horizontal: 16.0),
              child: Text(
                // dataGridCell.value.toString(),
                "123thisisareallylongemail@longemaildomain.com",
                // overflow: TextOverflow.ellipsis,
                style: GTTextStyle.body,
                softWrap: false,
              )),
        );
      }

      if (dataGridCell.columnName == 'height') {
        if (dataGridCell.value == null) return Container();
        return Container(
            alignment: Alignment.centerLeft,
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            child: Text(
              dataGridCell.value.toString(),
              // overflow: TextOverflow.ellipsis,
              style: GTTextStyle.body,
              softWrap: false,
            ));
      }

      return Container();
    }).toList());
  }
}
Tamilarasan-Paranthaman commented 2 years ago

Hi @daveshirman,

You are using a different text style for the cell widget. By default, the cell width is calculated based on the default text style. To calculate the cell width based on different TextStyle, just override the computeHeaderCellWidth method for header and computeCellWidth method for cell and return the super method with the required TextStyle. Please check the following sample and code snippet.

In DataGrid:

  final CustomColumnSizer _customColumnSizer = CustomColumnSizer();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter SfDataGrid'),
      ),
      body: SfDataGrid(
          source: _employeeDataSource,
          columns: getColumns,
          columnSizer: _customColumnSizer,
          columnWidthMode: ColumnWidthMode.auto),
    );
  }

In DataGridSource:

class EmployeeDataSource extends DataGridSource {

…

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      return Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          child: Text(
            dataGridCell.value.toString(),
            style: const TextStyle(fontWeight: FontWeight.bold),
            softWrap: false,
          ));
    }).toList());
  }
}

In ColumnSizer:

class CustomColumnSizer extends ColumnSizer {
  @override
  double computeHeaderCellWidth(GridColumn column, TextStyle style) {
    style = const TextStyle(fontWeight: FontWeight.bold);

    return super.computeHeaderCellWidth(column, style);
  }

  @override
  double computeCellWidth(GridColumn column, DataGridRow row, Object? cellValue,
      TextStyle textStyle) {
    textStyle = const TextStyle(fontWeight: FontWeight.bold);

    return super.computeCellWidth(column, row, cellValue, textStyle);
  }
}

Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/main-621685425

image

Also, we have already provided examples in our UG documentation. Please go through this,

UG Documentation: https://help.syncfusion.com/flutter/datagrid/columns-sizing?cs-save-lang=1&cs-lang=dart#autofit-calculation-based-on-different-textstyle

We hope this helps. Please let us know if you require any further assistance on this. We will be happy to assist you.

Regards, Tamilarasan

daveshirman commented 2 years ago

Thank you. Although in the documentation, I guess it just wasn't obvious.