I have a custom Selectbox created in flutter, on focus it opens and I am able to naviagte between the items with the arrowkeys (upd, donw) and select an item with enter, the overlay is attached to a readonly textfield, I handle the keyboard events on the focusnode of the textfield.
All that works good but if the list is longer I would like to scroll the itemlist automatically to the highlighted element. But the list inside the overlay doesnt updates even if I update the scrollcontrollers position with the .jumpTo
method, but the update doesnt show up on the overlay, but if I initialize the scrollController with an initial value, that shows up, so the controller is definetly connected with the given ListView.builder
.
I had a similar issue with state updates but in that case .markNeedsBuild();
method of the overlay entry helped. Any way to update a listview scroll position inside an overlay?
Overlay code currently a bit messy still in progress.
void showOverlay() {
final overlay = Overlay.of(context);
final renderbox = context.findRenderObject() as RenderBox;
final size = renderbox.size;
final offset = renderbox.localToGlobal(Offset.zero);
entry = OverlayEntry(
builder: (context) => Positioned(
width: size.width,
height: widget.items.length > 3
? 120
: (widget.items.length == 0 ? 40 : widget.items.length * 40),
child: CompositedTransformFollower(
showWhenUnlinked: false,
link: layerlink,
offset: Offset(0, size.height),
child: Container(
key: Key("Select$highlighted"),
color: Color(0xFF202020),
child: DefaultTextStyle(
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w300,
),
child: widget.items.length == 0
? GestureDetector(
onTap: () {
hideOverlay();
},
child: Container(
height: 40,
color: Colors.transparent,
padding: EdgeInsets.symmetric(horizontal: 12),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Empty",
style: TextStyle(fontSize: 14),
)),
),
)
: ListView.builder(
constroller: scrollController,
itemCount: widget.items.length,
itemBuilder: ((context, index) => GestureDetector(
onTap: () {
controller.text = widget.items[index].key;
hideOverlay();
if (widget.onChanged != null) {
widget.onChanged!(
widget.items[index].value);
}
focusNode.nextFocus();
},
child: Container(
height: 40,
color: highlighted == index
? Colors.red
: Colors.transparent,
padding:
EdgeInsets.symmetric(horizontal: 12),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
widget.items[index].key,
style: TextStyle(fontSize: 14),
)),
),
)))),
))));
overlay!.insert(entry!);
setState(() {
isOpen = true;
});
}