You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter Row组件中防止文本溢出并实现段落式换行?

Flutter Row布局长文本溢出问题解决

问题描述

开发跨平台应用时,InfoRow组件内的长文本在Row布局中会溢出,引发布局异常。已尝试设置softWrap和overflow属性,但文本仍无法在可用空间内自动换行。

预期效果

value文本能在可用空间内自动换行、流畅排布,无溢出错误。

当前问题

文本未按预期换行,出现布局溢出。

代码片段

info_row.dart

用于展示标签与值配对的组件,长文本时出现溢出:

import 'package:flutter/material.dart';
import 'package:solidcheck_admin/core/constants/app_colors.dart';

class InfoRow extends StatelessWidget {
  final String label;
  final String value;

  const InfoRow({required this.label, required this.value, Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      scrollDirection: Axis.vertical,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 150.0,
            child: Text(
              label,
              style: const TextStyle(
                fontWeight: FontWeight.w400,
                color: AppColors.textGrey,
                fontSize: 14.0,
              ),
            ),
          ),
          Text(
            value,
            textWidthBasis: TextWidthBasis.longestLine,
            softWrap: true,
            overflow: TextOverflow.ellipsis,
            maxLines: 6,
            style: const TextStyle(
              fontWeight: FontWeight.w400,
              color: AppColors.textBlack,
              fontSize: 14.0,
            ),
          ),
        ],
      ),
    );
  }
}

applicant_header_widget.dart

承载InfoRow的父组件,在多屏幕复用:

import 'package:flutter/material.dart';
import 'package:solidcheck_admin/data/models/applicant_list.dart';
import 'package:solidcheck_admin/ui/widgets/app/custom_button.dart';
import 'package:solidcheck_admin/ui/widgets/main/tabbar/info_rows.dart';

class ApplicantHeaderDetails extends StatelessWidget {
  final ApplicantListModel applicantModelValue;

  const ApplicantHeaderDetails({
    Key? key,
    required this.applicantModelValue,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;

    return Container(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _profileInfo(size),
              const SizedBox(height: 30.0),
              Row(
                children: [
                  CustomButton(title: 'Button 1', onPressed: () {}),
                  const SizedBox(width: 8.0),
                  CustomButton(title: 'Button 2', onPressed: () {}),
                  const SizedBox(width: 8.0),
                  CustomButton(title: 'Button 3', onPressed: () {}),
                  const SizedBox(width: 8.0),
                  CustomButton(title: 'Button 4', onPressed: () {}),
                  const SizedBox(width: 8.0),
                  CustomButton(title: 'Button 5', onPressed: () {}),
                ],
              ),
            ],
          ),
          const SizedBox(width: 100.0),
          Container(
            width: size.width * 0.50,
            child: const Wrap(
              spacing: 10.0,
              runSpacing: 10.0,
              children: [
                InfoRow(label: 'Date created:', value: 'Monday, 14-Nov-2022 09:50'),
                InfoRow(label: 'Last updated:', value: 'Friday, 12-July-2023 22:55'),
                InfoRow(label: 'Applicant Status:', value: 'New'),
                InfoRow(label: 'Applicant Status Date:', value: 'Friday, 12-July-2023 22:55'),
                InfoRow(label: 'Consent user:', value: 'Unknown'),
                InfoRow(label: 'Job Title:', value: 'Cleaner'),
                InfoRow(label: 'Check requested:', value: 'Basic Disclosure'),
                InfoRow(label: 'Online status:', value: 'Applicant created by requester'),
                InfoRow(label: 'Requested by:', value: 'Mike Ross\n004407546604213/\n004407546604213\nghjk@yahoo.com'),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _profileInfo(Size size) {
    return Row(
      children: [
        Container(
          height: size.height * 0.18,
          width: size.width * 0.09,
          decoration: BoxDecoration(
            color: Colors.grey[300],
            borderRadius: BorderRadius.circular(8.0),
          ),
          child: const Icon(Icons.image, size: 50.0, color: Colors.grey),
        ),
        const SizedBox(width: 10.0),
        const Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Thom World', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0, color: Colors.black)),
            SizedBox(height: 4.0),
            Text('Send disclosure to client (cannot use eBulk)', style: TextStyle(color: Colors.grey, fontSize: 14.0)),
            SizedBox(height: 8.0),
            Text('Service level 1', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500, fontSize: 14.0)),
            SizedBox(height: 4.0),
            Text('Primary requester: Test company', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400, fontSize: 14.0)),
          ],
        ),
      ],
    );
  }
}

解决方案

问题根源是Row布局中右侧Text未被限制宽度,无法触发自动换行。修改InfoRow组件,核心调整如下:

  1. 用Expanded包裹右侧Text,使其占据Row剩余空间
  2. 移除多余的SingleChildScrollView(无需垂直滚动)
  3. 移除textWidthBasis属性(干扰自动换行逻辑)
  4. 增加label与value间的间距,优化布局

修改后的info_row.dart代码:

import 'package:flutter/material.dart';
import 'package:solidcheck_admin/core/constants/app_colors.dart';

class InfoRow extends StatelessWidget {
  final String label;
  final String value;

  const InfoRow({required this.label, required this.value, Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(
          width: 150.0,
          child: Text(
            label,
            style: const TextStyle(
              fontWeight: FontWeight.w400,
              color: AppColors.textGrey,
              fontSize: 14.0,
            ),
          ),
        ),
        const SizedBox(width: 8.0),
        Expanded(
          child: Text(
            value,
            softWrap: true,
            overflow: TextOverflow.ellipsis,
            maxLines: 6,
            style: const TextStyle(
              fontWeight: FontWeight.w400,
              color: AppColors.textBlack,
              fontSize: 14.0,
            ),
          ),
        ),
      ],
    );
  }
}

修改后,value文本会自动填充剩余空间并换行,彻底解决溢出问题,符合预期布局效果。

内容的提问来源于stack exchange,提问作者Muhammad Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:34:58