Flutter折疊控件使用方法詳解

本文實例為大傢分享瞭Flutter折疊控件使用的具體代碼,供大傢參考,具體內容如下

1.官方折疊控件ExpansionTiles

官方默認提供瞭一個折疊控件 ExpansionTiles 主要用於listView做折疊和展開操作的,先來看看一般的用法

Widget _buildTiles(Entry root) {
    return new ExpansionTile(
      title: new Text(root.title),
      children: root.children.map(_buildTiles).toList(),
    );
  }

title 一般就是點擊的標題,可以是任意的Widget

children 是折疊和展開的List

使用很方便

2.自定義折疊控件ExpansionLayout

由於項目中的使用到的折疊控件是由外部Widget控制的,涉及到一些業務邏輯,使用官方控件ExpansionTiles,存在諸多不便,於是查看ExpansionTiles ,根據ExpansionTiles源碼做自己的修改,主要是根據外部傳入的字段來控制展開和折疊

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

const Duration _kExpand = Duration(milliseconds: 200);

class ExpansionLayout extends StatefulWidget {
  const ExpansionLayout({
    Key key,
    this.backgroundColor,
    this.onExpansionChanged,
    this.children = const <Widget>[],
    this.trailing,
    this.isExpanded,
  }) : super(key: key);

  final ValueChanged<bool> onExpansionChanged;
  final List<Widget> children;

  final Color backgroundColor;
  //增加字段控制是否折疊
  final bool isExpanded;

  final Widget trailing;

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

class _ExpansionLayoutState extends State<ExpansionLayout>
    with SingleTickerProviderStateMixin {
//折疊展開的動畫,主要是控制height
  static final Animatable<double> _easeInTween =
      CurveTween(curve: Curves.easeIn);
  AnimationController _controller;
  Animation<double> _heightFactor;

  bool _isExpanded;

  @override
  void initState() {
    super.initState();
    //初始化控制器以及出事狀態
    _controller = AnimationController(duration: _kExpand, vsync: this);
    _heightFactor = _controller.drive(_easeInTween);
    _isExpanded = widget.isExpanded;
    if (_isExpanded) _controller.value = 1.0;
  }

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

  void _handleTap() {
    setState(() {
      _isExpanded = widget.isExpanded;
      if (_isExpanded) {
        _controller.forward();
      } else {
        _controller.reverse().then<void>((void value) {
          if (!mounted) return;
        });
      }
      //保存頁面數據
      PageStorage.of(context)?.writeState(context, _isExpanded);
    });
    //回調展開事件
    if (widget.onExpansionChanged != null)
      widget.onExpansionChanged(_isExpanded);
  }

  Widget _buildChildren(BuildContext context, Widget child) {
    return Container(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          ClipRect(
            child: Align(
              heightFactor: _heightFactor.value,
              child: child,
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    //執行以下對應的Tap事件
    _handleTap();
    final bool closed = !_isExpanded && _controller.isDismissed;
    return AnimatedBuilder(
      animation: _controller.view,
      builder: _buildChildren,
      child: closed ? null : Column(children: widget.children),
    );
  }
}

原理其實很簡單,就是根據字段_isExpanded 來控制折疊和展開,內部使用動畫實現對height的控制

Flutter 目前生態資源還是很缺乏,很多需要自定義,一般根據系統相關的控件做修改,是最好的

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: