skip to Main Content

In the following example I have a SelectableRegion containing a list of text widgets and I call setState() every second. If I remove ‘SelectionContainer.disabled’ in ‘TextWidget’ then the selection state survives setState, otherwise it loses the text selection. Can you please why this issue happens and how to properly fix it?

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:lets_hang/locations/map_text_selection.dart';
import 'dart:math' as math;

class SelectionTest extends StatefulWidget {
  const SelectionTest({Key? key}) : super(key: key);

  @override
  State<SelectionTest> createState() => _SelectionTestState();
}

class _SelectionTestState extends State<SelectionTest> {
  final _selectableRegionFocusNode = FocusNode();
  late final Timer _timer;
  var count = 1;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(const Duration(milliseconds: 1500), (timer) {
      count++;
      setState(() {});
    });
  }

  @override
  dispose() {
    _selectableRegionFocusNode.dispose();
    _timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SelectableRegion(
      selectionControls: MapTextSelectionControls(),
      focusNode: _selectableRegionFocusNode,
      child: Container(
        width: 200,
        height: 300,
        color: Color((math.Random().nextDouble() * 0xFFFFFF).toInt())
            .withOpacity(1.0),
        child: ListView.builder(
          itemBuilder: (context, index) => TextWidget(key: ValueKey(index)),
          itemCount: count,
        ),
      ),
    );
  }
}

class TextWidget extends StatelessWidget {
  const TextWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final textSpans = <InlineSpan>[
      const TextSpan(text: 'Hey 123 456 789'),
      WidgetSpan(
        child: SelectionContainer.disabled(
          child: Text(
            '-> No issue if I remove SelectionContainer.disabled <-',
            maxLines: 1,
            style: Theme.of(context)
                .textTheme
                .bodyMedium!
                .copyWith(color: Colors.transparent),
          ),
        ),
      ),
    ];

    return Text.rich(TextSpan(children: textSpans));
  }
}

2

Answers


  1. There is a solution , that is you will take the chat bubble and put it in a stateless or statefull class . then call it in your current class and before it add const .

    Login or Signup to reply.
  2. Without some more code is really difficult to know, but assuming that what you can try to wrap with a StatefulBuilder the widget that throws the setState and isolate it with it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search