Flutter之页面布局二

目录:

    • 1、列表布局
      • 1.1、基础列表
      • 1.2、水平滑动的列表
      • 1.3、网格列表
      • 1.3、不同列表项的列表
      • 1.4、包含间隔的列表
      • 1.6、长列表
    • 2、滚动
      • 2.1、浮动的顶栏
      • 2.2、平衡错位滚动

1、列表布局

1.1、基础列表

在这里插入图片描述

import 'package:flutter/material.dart';void main() => runApp(const MyApp());class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const title = 'Basic List';return MaterialApp(title: title,home: Scaffold(appBar: AppBar(title: const Text(title)),body: ListView(children: const <Widget>[ListTile(leading: Icon(Icons.map), title: Text('Map')),ListTile(leading: Icon(Icons.photo_album), title: Text('Album')),ListTile(leading: Icon(Icons.phone), title: Text('Phone')),],),),);}
}

1.2、水平滑动的列表

在这里插入图片描述

import 'package:flutter/material.dart';void main() => runApp(const MyApp());class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const title = 'Horizontal List';return MaterialApp(title: title,home: Scaffold(appBar: AppBar(title: const Text(title)),body: Container(margin: const EdgeInsets.symmetric(vertical: 20),height: 200,child: ListView(// This next line does the trick.scrollDirection: Axis.horizontal,children: <Widget>[Container(width: 160, color: Colors.red),Container(width: 160, color: Colors.blue),Container(width: 160, color: Colors.green),Container(width: 160, color: Colors.yellow),Container(width: 160, color: Colors.orange),],),),),);}
}

1.3、网格列表

在这里插入图片描述

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const title = 'Grid List';return MaterialApp(title: title,home: Scaffold(appBar: AppBar(title: const Text(title)),body: GridView.count(// Create a grid with 2 columns.// If you change the scrollDirection to horizontal,// this produces 2 rows.crossAxisCount: 2,// Generate 100 widgets that display their index in the list.children: List.generate(100, (index) {return Center(child: Text('Item $index',style: TextTheme.of(context).headlineSmall,),);}),),),);}
}

1.3、不同列表项的列表

在这里插入图片描述

import 'package:flutter/material.dart';void main() {runApp(MyApp(items: List<ListItem>.generate(1000,(i) =>i % 6 == 0? HeadingItem('Heading $i'): MessageItem('Sender $i', 'Message body $i'),),),);
}class MyApp extends StatelessWidget {final List<ListItem> items;const MyApp({super.key, required this.items});Widget build(BuildContext context) {const title = 'Mixed List';return MaterialApp(title: title,home: Scaffold(appBar: AppBar(title: const Text(title)),body: ListView.builder(// Let the ListView know how many items it needs to build.itemCount: items.length,// Provide a builder function. This is where the magic happens.// Convert each item into a widget based on the type of item it is.itemBuilder: (context, index) {final item = items[index];return ListTile(title: item.buildTitle(context),subtitle: item.buildSubtitle(context),);},),),);}
}/// The base class for the different types of items the list can contain.
abstract class ListItem {/// The title line to show in a list item.Widget buildTitle(BuildContext context);/// The subtitle line, if any, to show in a list item.Widget buildSubtitle(BuildContext context);
}/// A ListItem that contains data to display a heading.
class HeadingItem implements ListItem {final String heading;HeadingItem(this.heading);Widget buildTitle(BuildContext context) {return Text(heading, style: Theme.of(context).textTheme.headlineSmall);}Widget buildSubtitle(BuildContext context) => const SizedBox.shrink();
}/// A ListItem that contains data to display a message.
class MessageItem implements ListItem {final String sender;final String body;MessageItem(this.sender, this.body);Widget buildTitle(BuildContext context) => Text(sender);Widget buildSubtitle(BuildContext context) => Text(body);
}

1.4、包含间隔的列表

在这里插入图片描述

import 'package:flutter/material.dart';void main() => runApp(const SpacedItemsList());class SpacedItemsList extends StatelessWidget {const SpacedItemsList({super.key});Widget build(BuildContext context) {const items = 4;return MaterialApp(title: 'Flutter Demo',debugShowCheckedModeBanner: false,theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),cardTheme: CardTheme(color: Colors.blue.shade50),),home: Scaffold(body: LayoutBuilder(builder: (context, constraints) {return SingleChildScrollView(child: ConstrainedBox(constraints: BoxConstraints(minHeight: constraints.maxHeight),child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween,crossAxisAlignment: CrossAxisAlignment.stretch,children: List.generate(items,(index) => ItemWidget(text: 'Item $index'),),),),);},),),);}
}class ItemWidget extends StatelessWidget {const ItemWidget({super.key, required this.text});final String text;Widget build(BuildContext context) {return Card(child: SizedBox(height: 100, child: Center(child: Text(text))));}
}

1.6、长列表

在这里插入图片描述

import 'package:flutter/material.dart';void main() {runApp(MyApp(items: List<String>.generate(10000, (i) => 'Item $i'),),);
}class MyApp extends StatelessWidget {final List<String> items;const MyApp({super.key, required this.items});Widget build(BuildContext context) {const title = 'Long List';return MaterialApp(title: title,home: Scaffold(appBar: AppBar(title: const Text(title)),body: ListView.builder(itemCount: items.length,prototypeItem: ListTile(title: Text(items.first)),itemBuilder: (context, index) {return ListTile(title: Text(items[index]));},),),);}
}

2、滚动

2.1、浮动的顶栏

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import 'package:flutter/material.dart';void main() => runApp(const MyApp());class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const title = 'Floating App Bar';return MaterialApp(title: title,home: Scaffold(// No appbar provided to the Scaffold, only a body with a// CustomScrollView.body: CustomScrollView(slivers: [// Add the app bar to the CustomScrollView.const SliverAppBar(// Provide a standard title.title: Text(title),// Allows the user to reveal the app bar if they begin scrolling// back up the list of items.floating: true,// Display a placeholder widget to visualize the shrinking size.flexibleSpace: Placeholder(),// Make the initial height of the SliverAppBar larger than normal.expandedHeight: 200,),// Next, create a SliverListSliverList(// Use a delegate to build items as they're scrolled on screen.delegate: SliverChildBuilderDelegate(// The builder function returns a ListTile with a title that// displays the index of the current item.(context, index) => ListTile(title: Text('Item #$index')),// Builds 1000 ListTileschildCount: 1000,),),],),),);}
}

2.2、平衡错位滚动

在这里插入图片描述

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';const Color darkBlue = Color.fromARGB(255, 18, 32, 47);void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),debugShowCheckedModeBanner: false,home: const Scaffold(body: Center(child: ExampleParallax())),);}
}class ExampleParallax extends StatelessWidget {const ExampleParallax({super.key});Widget build(BuildContext context) {return SingleChildScrollView(child: Column(children: [for (final location in locations)LocationListItem(imageUrl: location.imageUrl,name: location.name,country: location.place,),],),);}
}class LocationListItem extends StatelessWidget {LocationListItem({super.key,required this.imageUrl,required this.name,required this.country,});final String imageUrl;final String name;final String country;final GlobalKey _backgroundImageKey = GlobalKey();Widget build(BuildContext context) {return Padding(padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),child: AspectRatio(aspectRatio: 16 / 9,child: ClipRRect(borderRadius: BorderRadius.circular(16),child: Stack(children: [_buildParallaxBackground(context),_buildGradient(),_buildTitleAndSubtitle(),],),),),);}Widget _buildParallaxBackground(BuildContext context) {return Flow(delegate: ParallaxFlowDelegate(scrollable: Scrollable.of(context),listItemContext: context,backgroundImageKey: _backgroundImageKey,),children: [Image.network(imageUrl, key: _backgroundImageKey, fit: BoxFit.cover),],);}Widget _buildGradient() {return Positioned.fill(child: DecoratedBox(decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.transparent, Colors.black.withValues(alpha: 0.7)],begin: Alignment.topCenter,end: Alignment.bottomCenter,stops: const [0.6, 0.95],),),),);}Widget _buildTitleAndSubtitle() {return Positioned(left: 20,bottom: 20,child: Column(mainAxisSize: MainAxisSize.min,crossAxisAlignment: CrossAxisAlignment.start,children: [Text(name,style: const TextStyle(color: Colors.white,fontSize: 20,fontWeight: FontWeight.bold,),),Text(country,style: const TextStyle(color: Colors.white, fontSize: 14),),],),);}
}class ParallaxFlowDelegate extends FlowDelegate {ParallaxFlowDelegate({required this.scrollable,required this.listItemContext,required this.backgroundImageKey,}) : super(repaint: scrollable.position);final ScrollableState scrollable;final BuildContext listItemContext;final GlobalKey backgroundImageKey;BoxConstraints getConstraintsForChild(int i, BoxConstraints constraints) {return BoxConstraints.tightFor(width: constraints.maxWidth);}void paintChildren(FlowPaintingContext context) {// Calculate the position of this list item within the viewport.final scrollableBox = scrollable.context.findRenderObject() as RenderBox;final listItemBox = listItemContext.findRenderObject() as RenderBox;final listItemOffset = listItemBox.localToGlobal(listItemBox.size.centerLeft(Offset.zero),ancestor: scrollableBox,);// Determine the percent position of this list item within the// scrollable area.final viewportDimension = scrollable.position.viewportDimension;final scrollFraction = (listItemOffset.dy / viewportDimension).clamp(0.0,1.0,);// Calculate the vertical alignment of the background// based on the scroll percent.final verticalAlignment = Alignment(0.0, scrollFraction * 2 - 1);// Convert the background alignment into a pixel offset for// painting purposes.final backgroundSize =(backgroundImageKey.currentContext!.findRenderObject() as RenderBox).size;final listItemSize = context.size;final childRect = verticalAlignment.inscribe(backgroundSize,Offset.zero & listItemSize,);// Paint the background.context.paintChild(0,transform:Transform.translate(offset: Offset(0.0, childRect.top)).transform,);}bool shouldRepaint(ParallaxFlowDelegate oldDelegate) {return scrollable != oldDelegate.scrollable ||listItemContext != oldDelegate.listItemContext ||backgroundImageKey != oldDelegate.backgroundImageKey;}}class Parallax extends SingleChildRenderObjectWidget {const Parallax({super.key, required Widget background}): super(child: background);RenderObject createRenderObject(BuildContext context) {return RenderParallax(scrollable: Scrollable.of(context));}void updateRenderObject(BuildContext context,covariant RenderParallax renderObject,) {renderObject.scrollable = Scrollable.of(context);}
}class ParallaxParentData extends ContainerBoxParentData<RenderBox> {}class RenderParallax extends RenderBoxwith RenderObjectWithChildMixin<RenderBox>, RenderProxyBoxMixin {RenderParallax({required ScrollableState scrollable}): _scrollable = scrollable;ScrollableState _scrollable;ScrollableState get scrollable => _scrollable;set scrollable(ScrollableState value) {if (value != _scrollable) {if (attached) {_scrollable.position.removeListener(markNeedsLayout);}_scrollable = value;if (attached) {_scrollable.position.addListener(markNeedsLayout);}}}void attach(covariant PipelineOwner owner) {super.attach(owner);_scrollable.position.addListener(markNeedsLayout);}void detach() {_scrollable.position.removeListener(markNeedsLayout);super.detach();}void setupParentData(covariant RenderObject child) {if (child.parentData is! ParallaxParentData) {child.parentData = ParallaxParentData();}}void performLayout() {size = constraints.biggest;// Force the background to take up all available width// and then scale its height based on the image's aspect ratio.final background = child!;final backgroundImageConstraints = BoxConstraints.tightFor(width: size.width,);background.layout(backgroundImageConstraints, parentUsesSize: true);// Set the background's local offset, which is zero.(background.parentData as ParallaxParentData).offset = Offset.zero;}void paint(PaintingContext context, Offset offset) {// Get the size of the scrollable area.final viewportDimension = scrollable.position.viewportDimension;// Calculate the global position of this list item.final scrollableBox = scrollable.context.findRenderObject() as RenderBox;final backgroundOffset = localToGlobal(size.centerLeft(Offset.zero),ancestor: scrollableBox,);// Determine the percent position of this list item within the// scrollable area.final scrollFraction = (backgroundOffset.dy / viewportDimension).clamp(0.0,1.0,);// Calculate the vertical alignment of the background// based on the scroll percent.final verticalAlignment = Alignment(0.0, scrollFraction * 2 - 1);// Convert the background alignment into a pixel offset for// painting purposes.final background = child!;final backgroundSize = background.size;final listItemSize = size;final childRect = verticalAlignment.inscribe(backgroundSize,Offset.zero & listItemSize,);// Paint the background.context.paintChild(background,(background.parentData as ParallaxParentData).offset +offset +Offset(0.0, childRect.top),);}
}class Location {const Location({required this.name,required this.place,required this.imageUrl,});final String name;final String place;final String imageUrl;
}const urlPrefix ='https://docs.flutter.dev/cookbook/img-files/effects/parallax';
const locations = [Location(name: 'Mount Rushmore',place: 'U.S.A',imageUrl: '$urlPrefix/01-mount-rushmore.jpg',),Location(name: 'Gardens By The Bay',place: 'Singapore',imageUrl: '$urlPrefix/02-singapore.jpg',),Location(name: 'Machu Picchu',place: 'Peru',imageUrl: '$urlPrefix/03-machu-picchu.jpg',),Location(name: 'Vitznau',place: 'Switzerland',imageUrl: '$urlPrefix/04-vitznau.jpg',),Location(name: 'Bali',place: 'Indonesia',imageUrl: '$urlPrefix/05-bali.jpg',),Location(name: 'Mexico City',place: 'Mexico',imageUrl: '$urlPrefix/06-mexico-city.jpg',),Location(name: 'Cairo', place: 'Egypt', imageUrl: '$urlPrefix/07-cairo.jpg'),
];

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARM------硬件程序开发

硬件程序开发流程 相关硬件的工作原理 理解硬件的工作原理&#xff0c;明确硬件的功能和用途。 硬件连接 将硬件设备正确连接到开发板上。 编写程序 根据硬件功能编写相应的程序代码。 调试验证 通过调试工具验证程序的正确性&#xff0c;确保硬件功能正常。 控制LED的…

《QT从基础到进阶·七十四》Qt+C++开发一个python编译器,能够编写,运行python程序改进版

1、概述 源码放在文章末尾 根据上一篇文章回顾下利用QtC实现了一个简易的python编译器&#xff0c;类似pycharm或vsCode这样的编译器&#xff0c;该python编译器目前实现了如下功能&#xff1a; &#xff08;1&#xff09;支持编写python程序 &#xff08;2&#xff09;编写代…

Winform MQTT客户端连接方式

项目中使用到Winform的数据转发服务&#xff0c;所以记录下使用到的方法。 一.创建单例模板 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp.Scripts {public class SingleTon&…

Windows强制删除任何你想删除的文件和文件夹

Windows强制删除任何你想删除的文件和文件夹 本教程适用于 Windows 10/11 系统&#xff0c;工具和命令均经过验证。 为什么删除会失败&#xff1f; 权限不足&#xff1a;文件或文件夹可能需要管理员权限才能删除。文件被占用&#xff1a;某个程序正在使用目标文件&#xff0c…

Jmeter如何使用MD5进行加密?

在软件测试中&#xff0c;使用 JMeter 对数据进行 MD5 加密是一项常见需求&#xff0c;尤其是在模拟用户登录等涉及密码加密的场景时。下面详细介绍在 JMeter 里运用 MD5 加密的具体步骤。 1. 添加 BeanShell 预处理器 JMeter 本身没有直接的 MD5 加密功能&#xff0c;但可以…

4-c语言中的数据类型

一.C 语⾔中的常量 1.生活中的数据 整数&#xff1a; 100,200,300,400,500 小数: 11.11 22.22 33.33 字母&#xff1a; a&#xff0c;b&#xff0c;c&#xff0c;d A&#xff0c;B&#xff0c;C&#xff0c;D 在 C 语⾔中我们把字⺟叫做字符. 字符⽤单引号引⽤。例如A’ 单词…

中钧科技通过数字赋能,编织“数字互联网”助力数字化进程!

时间飞逝转眼间2025年已过去四分之一&#xff0c;作为一名95后回顾当下的生活&#xff0c;忍不住感慨10年和现在的对比。发现现在的手机支付、网上挂号、APP打车、在线学习、网络订餐、线上协同办公都以逐渐成为人们生活、工作的常态。也正是在这样的常态背景下&#xff0c;加快…

AI重塑云基础设施,亚马逊云科技打造AI定制版IaaS“样板房”

AI正在彻底重塑云基础设施。 IDC最新《2025年IDC MarketScape&#xff1a;全球公有云基础设施即服务&#xff08;IaaS&#xff09;报告》显示&#xff0c;AI正在通过多种方式重塑云基础设施&#xff0c;公有云IaaS有望继续保持快速增长&#xff0c;预计2025年全球IaaS的整体规…

高效深度学习lecture01

lecture01 零样本学习(Zero-Shot Learning, ZSL)&#xff1a; 模型可以在没有见过某种特定任务或类别的训练样本的情况下&#xff0c;直接完成对应的任务 利用知识迁移 模型在一个任务上训练时学到的知识&#xff0c;能够迁移到其他任务上比如&#xff0c;模型知道“狗”和“…

使用 iPerf 测试内网两台机器之间的传输速度

在现代网络管理中&#xff0c;确保内部网络&#xff08;内网&#xff09;的高效运行是至关重要的。为了评估和优化网络性能&#xff0c;我们需要一种可靠的方法来测试内网中不同设备间的传输速率。iPerf 作为一款广泛使用的工具&#xff0c;能够帮助我们准确测量两个节点之间的…

视频设备轨迹回放平台EasyCVR如何搭建公共娱乐场所远程视频监控系统

一、背景介绍 由于KTV、酒吧、足疗店等服务场所人员流动频繁、环境复杂&#xff0c;一直是治安管理的重点区域。为有效打击 “黄赌毒”、打架斗殴、寻衅滋事等违法犯罪的活动&#xff0c;打造安全有序的娱乐消费环境&#xff0c;我国相关部门将加大对这类场所的清查与管控力度…

vue进度条组件

<div class"global-mask" v-if"isProgress"><div class"contentBox"><div class"progresstitie">数据加载中请稍后</div><el-progress class"progressStyle" :color"customColor" tex…

Css:如何解决绝对定位子元素内容被父级元素overflow:hidden属性剪裁

一、问题描述 今天小伙伴提了一个bug&#xff0c;在点击列表项的“…”按钮应该出现的悬浮菜单显示不完整&#xff1a; 二、问题排查 一般这种问题&#xff0c;是由于悬浮菜单采用的是绝对定位&#xff0c;而父级采用了overflow:hidden属性。但需要注意的是&#xff0c;这里的…

JavaScript基础--01-JS简介

字面量&#xff1a;数字、字符串、布尔值 前言JavaScript背景Web前端有三层&#xff1a;发展历史JavaScript的发展&#xff1a;蒸蒸日上 JavaScript介绍JavaScript入门易学性JavaScript是脚本语言JavaScript的组成 JavaScript 的特点特点1&#xff1a;解释型语言特点2&#xff…

[leetcode] 面试经典 150 题——篇9:二叉树(番外:二叉树的遍历方式)

二叉树的遍历是指按照某种顺序访问二叉树中的每个节点。常见的遍历方式有四种&#xff1a;前序遍历&#xff08;Pre-order Traversal&#xff09;、中序遍历&#xff08;In-order Traversal&#xff09;、后序遍历&#xff08;Post-order Traversal&#xff09;以及层序遍历&am…

es基本概念

Elasticsearch 的架构与基本概念 Elasticsearch&#xff08;简称 ES&#xff09;是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它被广泛用于全文搜索、日志分析、实时数据分析等场景。以下是其架构概述及其基本概念的详细解释。 Elasticsearch 的架…

《星环之城:量子迷雾下的网络安全战记》

点击下面图片带您领略全新的嵌入式学习路线 &#x1f525;爆款热榜 88万阅读 1.6万收藏 序章&#xff1a;星环之陨 公元2145年&#xff0c;人类在火星轨道上建造了“星环之城”——一座由量子网络连接的太空城邦。它的中枢AI“盖娅”掌控着地球与殖民地的数据洪流&#xff…

《全栈+双客户端Turnkey方案》架构设计图

今天分享一些全栈双客户端Turnkey方案的架构与结构图。 1&#xff1a;三种分布式部署方案:网关方案&#xff0c;超级服务器单服方案&#xff0c;直连逻辑服方案 2: 单服多线程核心架构: 系统服务逻辑服服务 3: 系统服务的多线程池调度设计 4:LogicServer Update与ECS架构&…

打破界限:Android XML与Jetpack Compose深度互操作指南

在现有XML布局项目中逐步引入Jetpack Compose是现代Android开发的常见需求。本指南将全面介绍混合使用的最佳实践、技术细节和完整解决方案。 一、基础配置 1.1 Gradle配置 android {buildFeatures {compose true}composeOptions {kotlinCompilerExtensionVersion "1.5.3…

React-narice安卓打包流程

**1. 生成签名密钥 在项目的 android/app 目录下生成签名密钥的步骤&#xff1a; 打开终端或命令提示符&#xff1a;导航到您的 React Native 项目的 android/app 目录。 运行以下命令生成密钥库文件&#xff1a; keytool -genkeypair -v -keystore my-release-key.keystor…