微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flutter 常见问题的下拉菜单

如何解决Flutter 常见问题的下拉菜单

嘿,任何人都可以将我引导到与我提供的图像类似的 Flutter 中的小部件或库。 我想要这个作为常见问题解答部分。最初只有问题应该是可见的,点击组件时它应该显示答案。

enter image description here

解决方法

我会选择 this library 或者如果您愿意,以下是我为自己的目的创建的小部件的片段:

import 'package:flutter/material.dart';


/// [CustomCollapsable] is collapsable widget which shows a [preview]
/// and a trailing with a [trailingText] by default. On tap the trailing or
/// its [trailingText],it animates to show the [child].

/// NOTE: [ExpansionTile] doesn't support layout changes,for example
/// moving trailing down or to hide the [preview] after expand the content.
/// [CustomCollapsable] is inspired on [ExpansionTile] with additional features.
class CustomCollapsable extends StatefulWidget {
  /// [Widget] shown when expanded
  final Widget child;

  /// [Widget] shown only when it is not expanded
  final Widget preview;

  /// [String] that goes on top of the trailing arrow
  final String trailingText;

  /// Callback [ValueChanged] function fired after animation
  final ValueChanged<bool> onExpansionChanged;

  const CustomCollapsable({
    Key key,@required this.preview,@required this.child,@required this.trailingText,this.onExpansionChanged,});

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

class _CustomCollapsableState extends State<CustomCollapsable>
    with SingleTickerProviderStateMixin {
  static final Animatable<double> _easeInTween = CurveTween(
    curve: Curves.easeIn,);
  static final Animatable<double> _halfTween = Tween<double>(
    begin: 0.0,end: 0.5,);

  AnimationController _controller;
  Animation<double> _heightFactor;
  Animation<double> _iconTurns;

  bool _isExpanded = false;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      duration: Duration(seconds: 1),vsync: this,);
    _iconTurns = _controller.drive(_halfTween.chain(_easeInTween));

    _heightFactor = _controller.drive(_easeInTween);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  bool get isClosed => !_isExpanded && _controller.isDismissed;

  void _handleTap() {
    setState(() {
      _isExpanded = !_isExpanded;

      if (_isExpanded) {
        _controller.forward();
      } else {
        _controller.reverse().then<void>((void value) {
          if (!mounted) return;
          setState(() {});
        });
      }

      PageStorage.of(context)?.writeState(context,_isExpanded);
    });

    if (widget.onExpansionChanged != null) {
      widget.onExpansionChanged(_isExpanded);
    }
  }

  Widget _buildTralling() {
    return GestureDetector(
      onTap: _handleTap,child: Padding(
        padding: const EdgeInsets.only(top: 15.0),child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[
            isClosed
                ? Text(widget.trailingText.toUpperCase())                      
                : const SizedBox(),RotationTransition(
              turns: _iconTurns,child: const Icon(Icons.expand_more),),],);
  }

  Widget _buildChild(BuildContext context,Widget child) {
    return Column(
      mainAxisSize: MainAxisSize.min,children: <Widget>[
        // Preview widget is visiable only when the parent is closed
        isClosed ? widget.preview : const SizedBox(),ClipRect(
          child: Align(
            heightFactor: _heightFactor.value,child: child,_buildTralling()
      ],);
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller.view,builder: _buildChild,child: isClosed ? null : widget.child,);
  }
}

您可以根据需要定义 childpreview 小部件。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。