首页 > 其他分享 >一统天下 flutter - widget 布局类(可以有多个子): CustomMultiChildLayout - 自定义多组件布局

一统天下 flutter - widget 布局类(可以有多个子): CustomMultiChildLayout - 自定义多组件布局

时间:2023-04-27 15:36:29浏览次数:47  
标签:widget 自定义 布局 组件 CustomMultiChildLayout size id constraints

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

一统天下 flutter - widget 布局类(可以有多个子): CustomMultiChildLayout - 自定义多组件布局

示例如下:

lib\widget\layout\custom_multi_child_layout.dart

/*
 * CustomMultiChildLayout - 自定义多组件布局
 *
 * 注:约束是从上向下传递的,尺寸是从下向上传递的
 */

import 'package:flutter/material.dart';
import 'package:flutter_demo/helper.dart';

class CustomMultiChildLayoutDemo extends StatefulWidget {
  const CustomMultiChildLayoutDemo({Key? key}) : super(key: key);

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

class _CustomMultiChildLayoutDemoState extends State<CustomMultiChildLayoutDemo> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("title"),),
      backgroundColor: Colors.orange,
      /// 自定义布局
      body: CustomMultiChildLayout(
        /// 通过指定的 delegate 实现具体的布局
        delegate: _MyMultiChildLayoutDelegate(),
        children: [
          /// 通过 LayoutId 指定需要布局的组件的 id
          LayoutId(
            id: 'a',
            child: Container(
              color: Colors.red,
            ),
          ),
          LayoutId(
            id: 'b',
            child: Container(
              width: 200,
              height: 200,
              color: Colors.green,
            ),
          ),
        ],
      ),
    );
  }
}

class _MyMultiChildLayoutDelegate extends MultiChildLayoutDelegate {

  /// 用于对每个子组件做布局
  @override
  void performLayout(Size size) {
    /// 这个 size 就是 CustomMultiChildLayout 的可用空间
    log("performLayout size:$size");

    /// 用于判断 CustomMultiChildLayout 的 children 内是否存在指定 id 的组件
    /// 在 CustomMultiChildLayout 的 children 内需要通过 LayoutId 指定组件的 id
    if (hasChild('a')) {

    }

    /// 对 id 为 a 的组件布局,父把约束告诉子,然后子会把自己的尺寸告诉父
    var size_a = layoutChild("a", BoxConstraints(minWidth: 100, minHeight: 100, maxWidth: 100, maxHeight: 100));
    /// 对 id 为 b 的组件布局,父把约束告诉子,然后子会把自己的尺寸告诉父
    var size_b = layoutChild("b", BoxConstraints(minWidth: 0, minHeight: 0, maxWidth: 100, maxHeight: size.height));

    /// 设置 id 为 a 的组件的位置
    positionChild("a", Offset(0, 0));
    /// 设置 id 为 b 的组件的位置
    positionChild("b", Offset(100, 100));
  }

  /// 当 MultiChildLayoutDelegate 发生变化时,通过这里决定是否需要重新布局
  @override
  bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) {
    return true;
  }

  /// constraints 为 CustomMultiChildLayout 的父传给 CustomMultiChildLayout 的约束
  /// 返回值为 CustomMultiChildLayout 根据约束决定的自己的尺寸
  @override
  Size getSize(BoxConstraints constraints) {
    var size = super.getSize(constraints);
    log('getSize constraints:$constraints, size:$size');
    return size;
  }

  /// constraints 为 CustomMultiChildLayout 传给 id 为 childId 的子的约束
  /// 返回值为子根据约束决定的自己的尺寸
  @override
  Size layoutChild(Object childId, BoxConstraints constraints) {
    var size = super.layoutChild(childId, constraints);
    log('layoutChild childId:$childId, constraints:$constraints, size:$size');
    return size;
  }
}

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

标签:widget,自定义,布局,组件,CustomMultiChildLayout,size,id,constraints
From: https://www.cnblogs.com/webabcd/p/flutter_lib_widget_layout_custom_multi_child_layout.html

相关文章

  • 一统天下 flutter - widget 容器类(只能有一个子): CustomSingleChildLayout - 自定义单
    源码https://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-widget容器类(只能有一个子):CustomSingleChildLayout-自定义单组件布局示例如下:lib\widget\container\custom_single_child_layout.dart/**CustomSingleChildLayout-自定义单组件布......
  • [React-Native]样式和布局
    一、基本样式(1)内联样式在组件里面定义样式<Textstyle={{color:'orange',fontSize:20}}>小字号内联样式</Text>(2)外联样式在组件里指向外面的样式<Textstyle={[styles.orange,styles.bigFontSize]}>大字号外联样式</Text>(3)样式具有覆盖性如果定义相同属性的样式,后面会覆......
  • Kivy页面布局中自定义组件位置的方法,可以通过指定组件的位置、尺寸和边距等属性来实现
    Python实现fromkivy.appimportAppfromkivy.uix.gridlayoutimportGridLayoutfromkivy.uix.buttonimportButtonclassMyGridLayout(GridLayout):  def__init__(self,**kwargs):    super(MyGridLayout,self).__init__(**kwargs)    self.cols=1......
  • Kivy盒子布局中自定义组件位置的方法,可以通过在盒子布局中添加pos_hint属性来指定组件
    Python实现fromkivy.appimportAppfromkivy.uix.boxlayoutimportBoxLayoutfromkivy.uix.buttonimportButtonclassMyBoxLayout(BoxLayout):  def__init__(self,**kwargs):    super(MyBoxLayout,self).__init__(**kwargs)    #添加按钮并指定位......
  • Kivy表格布局(Grid Layout)中自定义组件位置的方法,可以通过指定组件的row和col属性来实
    Python实现fromkivy.appimportAppfromkivy.uix.gridlayoutimportGridLayoutfromkivy.uix.buttonimportButtonclassMyGridLayout(GridLayout):  def__init__(self,**kwargs):    super(MyGridLayout,self).__init__(**kwargs)    self.cols=3......
  • RK3568用户自定义开机画面功能
    RK方案中的开机画面处画逻辑在RK的方案中,如RK1109,RK1126,RK3568这些嵌入式LINUX方案在开机画面的处理逻辑都是一致的.用户的uboot,kernel开机画面都是同dts,kernel一起入在一个boot.img文件中的.boot.img的文件结构,基本又同Android的boot文件结构类似,具体的文件结构,可以参考uboo......
  • flex布局
    flex布局在CSS3中flex可以非常便捷的可以帮助我们实现对页面的布局。传统的页面布局,基于div+float来实现。flex可以快速实现页面的布局(很方便)。关于flex布局你必须要了解的有一下几点:<divclass="menu"样式><divclass="item"样式>112</div><divclass="item">......
  • #PowerBI 利用format函数,自定义格式显示
    PowerBI是一款强大的数据分析和可视化工具,它可以帮助我们快速地创建各种报表和仪表盘,展示数据的洞察和价值。在PowerBI中,有许多内置的函数可以帮助我们处理和转换数据,其中一个常用的函数就是Format函数。Format函数的作用是将一个值按照指定的格式进行显示,例如日期、时间、货币......
  • CefSharp自定义缓存实现
    大家好,我是沙漠尽头的狼。上文介绍了《C#使用CefSharp内嵌网页-并给出C#与JS的交互示例》,本文介绍CefSharp的缓存实现,先来说说添加缓存的好处:提高页面加载加速:CefSharp缓存可以缓存已经加载过的页面和资源,当用户再次访问相同的页面时,可以直接从缓存中加载,而不需要重新下载和解......
  • 博客园自定义皮肤设置
    目录博客园自定义皮肤设置1.选择皮肤darkgreentrip2.博客侧边栏公告3.页面定制css代码4.页首HTML代码博客园自定义皮肤设置1.选择皮肤darkgreentrip2.博客侧边栏公告<style>#back-top{position:fixed;bottom:10px;right:5px;z-index:99;}#ba......