Flutter GridView简介

GridView import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget....

November 3, 2021 · 1 min · alvazu

Flutter Sliver组件全解

一、初试Sliver 1.1 使用Sliver制作一个ListView ​ ListView的底层原理就是Sliver,我们可以用CustomScrollView先做出一个视窗(所谓视窗就是里面的内容比边框大),在其中使用SliverChildBuilderDelegate,而事实上,这也正是ListViewBuilder的底层做法。 CustomScrollView( //定义一个视窗 slivers: [ SliverList(delegate: SliverChildBuilderDelegate((context, index) { return Container( height: 200, color: Colors.primaries[index%Colors.primaries.length], ); })) ], ) 1.2 更加灵活的ListView——加入任意Widget ​ 而使用Sliver,我们就可以实现更加灵活的功能,例如在顶部加入一个FlutterLogo: CustomScrollView( slivers: [ SliverToBoxAdapter(child: FlutterLogo(size:100),), //加入一个FlutterLogo SliverList( delegate: SliverChildBuilderDelegate((context, index) { //使用SliverChildBuilderDelegate实现动态加载(Builder) //delegate: SliverChildListDelegate对应不用Builder的ListView return Container( height: 200, color: Colors.primaries[index%Colors.primaries.length], ); })) ], ) 1.3 更加灵活的ListView——组合GridView ​ 我们也可以尝试组合GridView: CustomScrollView( slivers: [ /* 1. 用SliverToBoxAdapter包裹的普通Widget */ const SliverToBoxAdapter(child: FlutterLogo(size:100),), /* 2....

November 3, 2021 · 2 min · alvazu

Flutter动画全解(三)底层自定义动画——Hero、CustomPainter和Rive

底层自定义动画 3.1 Flutter动画原理 ​ Flutter内部通过setState()函数刷新页面,且flutter优化得相当好,一秒执行60/120次也不会有卡顿。 ​ Ticker原理:屏幕每刷新一帧,称为一个ticker: Ticker _ticker = Ticker((elapsed) { print("Tick: $elapsed"); //elapsed是运行总时长 })..start(); ​ 你可以通过下列方式手动制作一个Ticker(仅作为实验用途,不推荐): double _height = 300; @override void initState(){ Ticker _ticker = Ticker((_) => setState((){ _height --; if(_height <= 0) _height = 300; }))..start(); super.initState(); } ​ 上述程序虽然可以运行,但首先,它没有考虑一些特殊情况,如程序暂时退出、切换到其他程序时,动画应该暂停。其次,每一帧时_height--,则在60帧的屏幕下该动画需要5秒执行完毕,而在120hz屏幕下只需要2.5秒。 3.2 Hero动画(主动画) ​ 将需要做Hero动画的控件包裹上Hero,并给它一个tag属性,两个页面对应控件的tag一致。 ​ 如果两个页面中的控件样式不一致,或者类型不统一,那么会瞬间切换,不会有控件切换时的动画效果。 3.3 CustomPaint ​ Tips:要使Container占满屏幕,使用 Container( constraints: BoxConstraints.expand(), //或者 width: double.infinity, height: double.infinity, ) 3.4 嵌入式Rive(Flare)插件动画 Rive New File

November 1, 2021 · 1 min · alvazu

Flutter动画全解(二)显式动画——Transition系列

显式动画——Transition系列(配合AnimationController) 2.1 循环旋转——RotationTransition ​ 我们需要使用RotationTransition配合AnimationController实现动画的手动控制,以实现隐式动画(Animated系列)无法完成的功能:循环重播、随时中断、多方协调等。 ​ 另外,要使用AnimationController,我们必须使用StatefulWidget,以使用生命周期函数initState()和dispose()。 ​ 我们先简单地看一个实例,在后文中,我们将详细解释其中的内容。 import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { MyApp({Key? key}) : super(key: key); @override _MyAppState createState() => _MyAppState(); } //SingleTickerProviderStateMixin用于垂直同步 class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { late AnimationController _controller; bool _loading = false; @override void initState() { _controller = AnimationController( duration: const Duration(seconds: 1), vsync: this, ); super.initState(); } @override void dispose() { _controller.dispose(); //用完删除,否则内存泄漏 super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: Container( width: 300, height: 120, color: Colors....

November 1, 2021 · 4 min · alvazu

Flutter动画全解(一)隐式动画——Animated系列

隐式动画——Animated系列 1.1 快速开始——AnimatedContainer //原始main.dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Container( //一个普普通通的Container width: 300, height: 300, color: Colors.blue, child: const Center( child: Text("Hi", style: TextStyle( fontSize: 72, )), ), ), )); } } //使用AnimatedContainer,并传入Duration,两行代码就可以动起来! import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: AnimatedContainer( //将Container换成AnimatedContainer duration: const Duration(seconds: 1), //同时加上duration参数即可 width: 300, height: 100, color: Colors....

November 1, 2021 · 3 min · alvazu