Need to have ListView.builder build ListTiles under certain part of Text inside RichText widget
Doing it with Stack widget, Im getting position of element in RichText by finding its Offset position, for this need to use Key, though TextSpan doesn't have Key property, so im using InkWell widget inside RichText instead (I presume I can turn off animations associated with it).
It works really well, ListTiles are following InkWell accordingly (need to add few lines of code to make it seamless).
Though still have big issue, can't get ListView.builder to display items that are outside of Text widget, can't wrap it in Extended() or Flexible() widget, getting error, incorrect use of parent widget, I presume that's because I use Stack widget and don't know what else to do. Please let me know if someone can solve this issue.
There are buttons on the page, so one can add or remove text, as to see it in action. And I've added Text before and after ListTile anchor element so it can be better seen as it is being displayed only inside Text widget
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
// notice "hot reload" button
primarySwatch: Colors.blue,
),
home: GetPosition(),
);
}
}
class GetPosition extends StatefulWidget {
String changeText =
'dynamicaly changing text dynamicaly changing text dynamicaly changing text dynamicaly changing text dynamicaly changing text dynamicaly changing text';
@override
_GetPositionState createState() => _GetPositionState();
}
class _GetPositionState extends State<GetPosition> {
GlobalKey _key = GlobalKey();
double _x = 0, _y = 0;
// this function is trigger when the user presses the floating button
void _getOffset(GlobalKey key) {
RenderBox? box = key.currentContext!.findRenderObject() as RenderBox?;
Offset position = box!.localToGlobal(Offset.zero);
setState(() {
_x = position.dx;
_y = position.dy;
});
}
@override
Widget build(BuildContext context) {
final List<String> entries = <String>[
_x != null ? "X: ${_x.toInt()}" : '',
_y != null ? "Y: $_y" : '',
_x != null ? 'Entry A' : '',
_x != null ? 'Entry B' : '',
_x != null ? 'EntryC' : ''
];
return Scaffold(
body: Stack(children: [
RichText(
textAlign: TextAlign.left,
text: TextSpan(
text: '${widget.changeText}',
style: TextStyle(color: Colors.black, fontSize: 18.0),
children: [
WidgetSpan(
child: InkWell(
splashFactory: NoSplash.splashFactory,
key: _key,
onTap: () {},
child: Text(
" ListView.builder",
style: TextStyle(color: Colors.red, fontSize: 18.0),
),
),
),
TextSpan(
text: '${widget.changeText}',
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
],
),
),
Positioned(
top: _y + 10,
left: _x,
child: SizedBox(
width: 310,
height: 200,
child: Builder(builder: (context) {
return ListView.builder(
padding: EdgeInsets.all(0.0),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
dense: true,
// height: 300,
// color: Colors.amber[colorCodes[index]],
title: Text(
'${entries[index]}',
style: TextStyle(color: Colors.red, fontSize: 18.0),
),
);
});
}),
),
),
Row(children: [
ElevatedButton(
onPressed: () {
// randomPosition();
_getOffset(_key);
widget.changeText = widget.changeText + ' add text dsds';
// print(randomLeft);
// print(randomTop);
setState(() {});
},
child: Text('Add some text')),
ElevatedButton(
onPressed: () {
_getOffset(_key);
if (widget.changeText.length > 10) {
widget.changeText = widget.changeText
.substring(10, widget.changeText.length - 1);
} else {
if (widget.changeText.length > 0) {
widget.changeText = widget.changeText
.substring(0, widget.changeText.length - 1);
} else {}
}
setState(() {});
},
child: const Text('Delete some Text'),
)
]),
]),
floatingActionButton: FloatingActionButton(
onPressed: () {
// randomPosition();
_getOffset(_key);
widget.changeText = widget.changeText + ' add text dsds';
// print(randomLeft);
// print(randomTop);
setState(() {});
},
child: Icon(Icons.calculate)),
);
}
}