Pass scrollcontroller to flutter overlay

652 views Asked by At

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.

SelectBox

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;
    });
  }
0

There are 0 answers