【问题标题】:How to make my page scrollable when i show overlay element, that have too many items in flutter?当我显示重叠元素时如何使我的页面可滚动,其中有太多的项目在颤动?
【发布时间】:2020-10-21 12:37:42
【问题描述】:

我创建了一个自定义下拉小部件,以从我从本地 json 文件加载的列表中选择一个选项。 当此下拉字段位于屏幕底部时,无法显示选项,因为使用了覆盖元素。 你能帮我吗,我该如何解决htis问题?

here is the image that shows my problem

这是我的自定义下拉菜单

import 'package:flutter/material.dart';

class CustomDropdown extends StatefulWidget {
  final TextEditingController controller;
  final List<Map> items;
  final String label;
  final String value;

  const CustomDropdown({Key key, @required this.controller, @required this.items, this.label, this.value}) : super(key: key);

  @override
  _CustomDropdownState createState() => _CustomDropdownState();
}

class _CustomDropdownState extends State<CustomDropdown> {
  final FocusNode _focusNode = FocusNode();
  OverlayEntry _overlayEntry;
  final LayerLink _layerLink = LayerLink();
  bool isOpened = false;

  @override
  void initState() {
    super.initState();
    widget.controller.text = widget.value;
    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        this._overlayEntry = this._createOverlayEntry();
        Overlay.of(context).insert(this._overlayEntry);
      } else {
        this._overlayEntry.remove();
      }
    });
  }

  OverlayEntry _createOverlayEntry() {
    RenderBox renderBox = context.findRenderObject();
    var size = renderBox.size;
    var offset = renderBox.localToGlobal(Offset.zero);

    return OverlayEntry(
      // opaque: true,
      builder: (context) => Positioned(
        // left: offset.dx,
        // top: offset.dy + size.height + 5.0,
        width: size.width,
        child: CompositedTransformFollower(
          link: this._layerLink,
          showWhenUnlinked: false,
          offset: Offset(0.0, size.height + 5.0),
          child: Material(
            elevation: 12.0,
            child: ListView.builder(
            padding: EdgeInsets.zero,
            scrollDirection: Axis.vertical,
            shrinkWrap: true, // new line
            // physics: NeverScrollableScrollPhysics(), // new line
            itemCount: widget.items.length,
            itemBuilder: (_, index) {
              return ListTile(
                title: Column(
                  children: [
                    SizedBox(
                      height: 20,
                    ),
                    Text(widget.items[index]["text"]),
                    SizedBox(
                      height: 20,
                    ),
                    Divider()
                  ],
                ),
                onTap: () {
                  print("${widget.items[index]["text"]} Tapped");
                  setState(() {
                    _focusNode.unfocus();
                    widget.controller.text = widget.items[index]["text"];
                  });
                },
              );

            },
          ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return CompositedTransformTarget(
      link: this._layerLink,
      child: TextFormField(
        controller: widget.controller,
        readOnly: true,
        // initialValue: 'Test',
        focusNode: this._focusNode,
        decoration: InputDecoration(
          labelText: widget.label.toUpperCase(),
          isDense: true,
        ),
      ),
    );
  }
}

我在这里使用它:

 Form(
          key: _formKey,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Wollen Sie Ihr Profile mit einem Passwort schützen?'.toUpperCase(),
                style: TextStyle(fontSize: 20.0, color: theme.inputTextColor),
              ),
              Padding(
                padding: const EdgeInsets.only(top: 15.0),
                child: _buildFaceIdOptions(),
              ),
              Padding(
                padding: const EdgeInsets.only(top: 15.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text(
                      'FaceID verwenden',
                      style: TextStyle(fontSize: 18.0),
                    ),
                    _buildToggleButton()
                  ],
                ),
              ),
              SizedBox(
                height: 20,
              ),
              Padding(
                padding: const EdgeInsets.only(top: 15.0),
                child: _buildPassword(),
              ),
              SizedBox(
                height: 20,
              ),
              Padding(
                padding: const EdgeInsets.only(top: 15.0),
                child: _buildRepeatPassword(),
              ),
              SizedBox(
                height: 20,
              ),
              Padding(padding: const EdgeInsets.only(top: 15.0), child: CustomDropdown(controller: questionController, items: _questionList, label: 'Sicherheitsfrage', value: '',)),
              SizedBox(
                height: 20,
              ),
              // Padding(
              //   padding: const EdgeInsets.only(top: 15.0),
              //   child: _buildPassword(),
              // ),
              SizedBox(
                height: 120,
              )
            ],
          ),
        )

【问题讨论】:

    标签: flutter


    【解决方案1】:

    您可以使 Overlay 内的列表可滚动。

    您必须在 OverlayEntry 内的 Positioned 小部件中设置所有可能的值,否则其内容将无法滚动:如果您设置 width 那么您还必须设置 top , bottomleft(或 right 但不是两者,请阅读 Positioned 小部件规范)。

    一旦您设置了这些值,Positioned 小部件的内容将是可滚动的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-22
      • 2015-05-26
      • 2021-04-30
      • 2022-12-16
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多