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
There is a solution , that is you will take the chat bubble and put it in a
stateless
orstatefull
class . then call it in your current class and before it addconst
.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.