Home > Mobile >  Flutter - How to know free screen size for text widget
Flutter - How to know free screen size for text widget

Time:04-25

In my flutter project, I've used ExpansionPanel and in it there are star icon, text, checkbox, popup window as shown in the picture. But when I insert more text it is overflowing. And here you can see three dots (...) and it's fixed. I did it manually when text lenght more than 15, then, It cuts the substring and adds ... at the end and full title can be shown when expansion panel expanded.

I want to do it dynamic, according to different width of screen. In this case how can I determine free space for the text widget?

enter image description here

import 'package:flutter/material.dart';

import '../blocs/multi_blocs.dart';
import '../models/task.dart';
import '../widgets/task_tile.dart';

class TasksList extends StatelessWidget {
  final List<Task> tasks;
  const TasksList({
    Key? key,
    required this.tasks,
  }) : super(key: key);

  void _cancelOrDeleteCallBack(BuildContext ctx, Task task) {
    task.isCancelled == false
        ? ctx.read<TodosBloc>().add(CancelTask(task: task))
        : ctx.read<TodosBloc>().add(DeleteTask(task: task));
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: GestureDetector(
        // behavior: HitTestBehavior.translucent,
        child: ExpansionPanelList.radio(
          elevation: 3,
          children: tasks
              .map(
                (task) => ExpansionPanelRadio(
                  headerBuilder: (context, isOpen) => Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 8),
                    child: TaskTile(
                      task: task,
                      checkboxCallback: (checkboxState) {
                        context.read<TodosBloc>().add(UpdateTask(task: task));
                      },
                      cancelOrDeleteCallback: () =>
                          _cancelOrDeleteCallBack(context, task),
                      likeCallback: () => context
                          .read<TodosBloc>()
                          .add(LikeOrDislikeTask(task: task)),
                      restoreCallback: () => context
                          .read<TodosBloc>()
                          .add(RestoreTask(task: task)),
                    ),
                  ),
                  body: ListTile(
                    title: SelectableText(
                      'Task:\n${task.title}\n\nDescription:\n${task.description}',
                      toolbarOptions: const ToolbarOptions(
                        copy: true,
                        selectAll: true,
                        cut: true,
                      ),
                    ),
                  ),
                  value: Text(task.id),
                ),
              )
              .toList(),
        ),
      ),
    );
  }
}

CodePudding user response:

We cant calculate the remaining screen for texts. just wrap your text with Expanded widget. and give overflow: TextOverflow.eclipse to text. it will solve your issue.

CodePudding user response:

I implemented your 'TaskTile' widget like your layout.

  • TaskTile
    -- Row
    --- Icon
    --- Expanded
    ---- Text(overflow: TextOverflow.ellipsis)
    --- CheckBox
    --- Hamburger button

enter image description here

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: _buildBody(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  Widget _buildBody() {
    return TasksList(
      tasks: [
        {
          'id': '123',
          'title': 'title1',
          'desc': 'desc',
        },
        {
          'id': '333',
          'title': 'title2',
          'desc': 'descasdfkjsklfjklasdjfklajsldkfalskdfj',
        }
      ],
    );
  }
}

class TasksList extends StatelessWidget {
  final List<Map<String, dynamic>> tasks;
  const TasksList({
    Key key,
    @required this.tasks,
  }) : super(key: key);

  // void _cancelOrDeleteCallBack(BuildContext ctx, Task task) {
  //   task.isCancelled == false
  //       ? ctx.read<TodosBloc>().add(CancelTask(task: task))
  //       : ctx.read<TodosBloc>().add(DeleteTask(task: task));
  // }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: GestureDetector(
        // behavior: HitTestBehavior.translucent,
        child: ExpansionPanelList.radio(
          elevation: 3,
          children: tasks
              .map(
                (task) => ExpansionPanelRadio(
                  headerBuilder: (context, isOpen) => Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 8),
                    child: Row(
                      children: [
                        Icon(Icons.favorite),
                        Expanded(
                          child: Text(
                            task['desc'],
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        Icon(Icons.add_box),
                        Icon(Icons.bug_report_rounded),
                      ],
                    ),
                  ),
                  body: ListTile(
                    title: SelectableText(
                      'Task:\n${task['title']}\n\nDescription:\n${task['desc']}',
                      toolbarOptions: const ToolbarOptions(
                        copy: true,
                        selectAll: true,
                        cut: true,
                      ),
                    ),
                  ),
                  value: Text(task['id']),
                ),
              )
              .toList(),
        ),
      ),
    );
  }
}
  • Related