赞
踩
- CustomMultiChildLayout(
- children: [LayoutId(child:Container(),id:"yourId") ],
- delegate: _delegate,
- )
1. 构造参数介绍
children:组件列表,需要使用LayoutId进行嵌套
delegate:代理类需自定义delegate实现MultiChildLayoutDelegate
2. LayoutId构造参数介绍
child:子组件,真正显示组件
id:组件对应id,不可重复,object类型
- class TestDelegate extends MultiChildLayoutDelegate{
- @override
- void performLayout(Size size) {
- // TODO: implement performLayout
- }
-
- @override
- bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) {
- // TODO: implement shouldRelayout
- throw UnimplementedError();
- }
- }
1. 方法介绍
performLayout:页面组件绘制过程,在此方法中绘制组件
shouldRelayout:是否重绘
2. performLayout内部实现
- idList.forEach((element) { //循环数据列表
- if (hasChild(element)) {
- Size viewSize =
- layoutChild(element, BoxConstraints(maxWidth: size.width)); //获取对应view尺寸,每个,注意BoxConstraints 需要注意如何计算尺寸
- if (x + viewSize.width > size.width) {
- line += 1;
- x = 0;
- y += change + runSpacing;
- change = 0;
- }
- positionChild(element, Offset(x, y));//根据坐标值绘制view,如果不调用,同样会绘制只是绘制在0,0位置
- x += viewSize.width + spacing;
- if (change < viewSize.height) {
- change = viewSize.height;
- }
- lastHeight = viewSize.height;
- }
- });
注意
layoutChild 每个id 只能调用一次
错误示范:
- double height = layoutChild(element, BoxConstraints(maxWidth: size.width)).height;
-
- double width= layoutChild(element, BoxConstraints(maxWidth: size.width)).width;
正确代码:
- double height = 0.0;
-
- double width = 0.0;
-
- Size size = layoutChild(element, BoxConstraints(maxWidth: size.width));
-
- height = size.height;
-
- width = size.width;
除非固定格式否则必须调用positionChild对子view 位置进行绘制
performLayout方法只是操作id
CustomMultiChildLayout 是一个无法自动测量内部组件尺寸的布局,组件大小需要外部传入,所以如果当组件直接放入可滑动组件会导致布局高度报错,本人解决方式是曲线救国,如果您有什么好的解决办法也请提出哦(联系方式QQ:243280864)
- ``
-
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/scheduler.dart';
- import 'package:zefyr/zefyr.dart';
-
- /**
- *
- @ProjectName: jiakeapp_live
-
- @ClassName: max_line_wrap
-
- @Description: dart文件描述
-
- @Author: 孙浩
-
- @QQ: 243280864
-
- @CreateDate: 2020/10/13 13:32
- */
-
-
-
- ///外部暴露组件
-
- class MaxLineWrap extends StatefulWidget {
- final List<Widget> children;
- final int maxLine;
- Widget expandedWidget;
- double horizontalSpacing = 0.0;
- double verticalSpacing = 0.0;
- Widget closeWidget;
-
- MaxLineWrap({
- @required this.children,
- @required this.maxLine,
- @required this.closeWidget,
- @required this.expandedWidget,
- this.verticalSpacing = 0.0,
- this.horizontalSpacing = 0.0,
- });
-
- @override
- _MaxLineWrapState createState() => _MaxLineWrapState();
- }
-
- ///state实现类
-
- class _MaxLineWrapState extends State<MaxLineWrap> {
- bool isExpanded = false;
- List<int> indexList = [];
- double height = 0.0;
- _MaxLineWrapDelegate _delegate;
-
- @override
- void initState() {
- super.initState();
- // widget.children.add(widget.moreWidget);
- for (int i = 0; i <= widget.children.length; i++) {
- indexList.add(i);
- }
- }
-
- @override
- Widget build(BuildContext context) {
- _delegate = _MaxLineWrapDelegate(indexList, widget.maxLine, widget.horizontalSpacing,
- widget.verticalSpacing, isExpanded, (height) {});
- return Container(
- child: _WrapLess(
- _delegate,
- indexList,
- isExpanded ? widget.closeWidget : widget.expandedWidget,
- widget.children, (timeStamp) {
- if (this.height != _delegate.getHeight()) {
- height = _delegate.getHeight();
- setState(() {});
- }
- }, () {
- setState(() {
- isExpanded = !isExpanded;
- });
- }),
- height: height,
- );
- }
-
- }
-
- ///曲线救国获取高度抽取组件
-
- class _WrapLess extends StatelessWidget {
- final _MaxLineWrapDelegate _delegate;
- final List<int> indexList;
- final List<Widget> viewList;
- final Widget lastView;
- final GestureTapCallback clickCallBack;
- final FrameCallback callback;
-
- _WrapLess(this._delegate, this.indexList, this.lastView, this.viewList,
- this.callback, this.clickCallBack) {
- WidgetsBinding.instance.addPostFrameCallback(callback);
- }
-
- @override
- Widget build(BuildContext context) {
- return CustomMultiChildLayout(
- children: indexList
- .map((e) => LayoutId(
- child: e != indexList.last
- ? viewList[e]
- : GestureDetector(
- child: lastView,
- onTap: clickCallBack,
- ),
- id: e,
- ))
- .toList(),
- delegate: _delegate,
- );
- }
- }
-
- class _MaxLineWrapDelegate extends MultiChildLayoutDelegate {
- final List<int> idList;
- final int maxLine;
- final double spacing;
- final double runSpacing;
- final bool isExpanded;
- final ValueChanged<double> heightChange;
- double viewHeight = 0.0;
- int line = 1;
- double lineWidth = 0;
- bool canDraw = true;
-
- _MaxLineWrapDelegate(this.idList, this.maxLine, this.spacing, this.runSpacing,
- this.isExpanded, this.heightChange);
-
- @override
- void performLayout(Size size) {
- double x = 0.0;
- double y = 0.0;
- double change = 0;
- double lastHeight = 0;
-
- if (!isExpanded) {
- Size lastSize =
- layoutChild(idList.last, BoxConstraints(maxWidth: size.width));
- idList.forEach((element) {
- if (hasChild(element) && element != idList.last) {
- Size viewSize =
- layoutChild(element, BoxConstraints(maxWidth: size.width));
- if (line != maxLine) {
- if (x + viewSize.width > size.width) {
- line += 1;
- x = 0;
- y += change + runSpacing;
- change = 0;
- }
- } else {
- if (x + viewSize.width + spacing + lastSize.width >= size.width &&
- !isExpanded) {
- // if (maxLine < line) {
- canDraw = false;
- // }
- lastHeight = lastSize.height;
- }
- }
- if (canDraw) {
- positionChild(element, Offset(x, y));
- x += viewSize.width + spacing;
- if (change < viewSize.height) {
- change = viewSize.height;
- lastHeight = viewSize.height;
- }
- } else {
- positionChild(element, Offset(-1000, -1000));
- }}
- });
-
- if(!canDraw){
- positionChild(idList.last, Offset(x, y));
- }else{
- positionChild(idList.last, Offset(-1000, -1000));
- }
-
- } else {
- idList.forEach((element) {
- if (hasChild(element)) {
- Size viewSize =
- layoutChild(element, BoxConstraints(maxWidth: size.width));
- if (x + viewSize.width > size.width) {
- line += 1;
- x = 0;
- y += change + runSpacing;
- change = 0;
- }
- positionChild(element, Offset(x, y));
- x += viewSize.width + spacing;
- if (change < viewSize.height) {
- change = viewSize.height;
- }
- lastHeight = viewSize.height;
- }
- });
- }
-
- viewHeight = y + lastHeight;
- }
-
- double getHeight() => viewHeight;
-
- void changeLine() {
- line += 1;
- lineWidth = 0;
- }
-
- @override
- bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) {
- return false;
- }
- }
- MaxLineWrap(
- children: short.data.classList
- .map((e) => buildWrapItem(e, short))
- .toList(),
- maxLine: 3,
- horizontalSpacing: W(20),
- verticalSpacing: W(16),
- closeWidget: buildLabelBtnWidget(
- "收起", Res.label_down),
- expandedWidget: buildLabelBtnWidget(
- "更多", Res.label_down))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。