翼度科技»论坛 编程开发 html5 查看内容

Flutter系列文章-Flutter UI进阶

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27

在本篇文章中,我们将深入学习 Flutter UI 的进阶技巧,涵盖了布局原理、动画实现、自定义绘图和效果、以及 Material 和 Cupertino 组件库的使用。通过实例演示,你将更加了解如何创建复杂、令人印象深刻的用户界面。
第一部分:深入理解布局原理

1. 灵活运用 Row 和 Column

Row 和 Column 是常用的布局组件,但灵活地使用它们可以带来不同的布局效果。例如,使用 mainAxisAlignment 和 crossAxisAlignment 可以控制子组件在主轴和交叉轴上的对齐方式。
  1. Row(
  2.   mainAxisAlignment: MainAxisAlignment.spaceBetween,
  3.   children: [
  4.     Container(width: 50, height: 50, color: Colors.red),
  5.     Container(width: 50, height: 50, color: Colors.green),
  6.     Container(width: 50, height: 50, color: Colors.blue),
  7.   ],
  8. )
复制代码
2. 弹性布局 Flex 和 Expanded

Flex 和 Expanded 可以用于实现弹性布局,让组件占据可用空间的比例。例如,下面的代码将一个蓝色容器占据两倍宽度的空间。
  1. Row(
  2.   children: [
  3.     Container(width: 50, height: 50, color: Colors.red),
  4.     Expanded(
  5.       flex: 2,
  6.       child: Container(height: 50, color: Colors.blue),
  7.     ),
  8.   ],
  9. )
复制代码
第二部分:动画和动效实现

1. 使用 AnimatedContainer

AnimatedContainer 可以实现在属性变化时自动产生过渡动画效果。例如,以下代码在点击时改变容器的宽度和颜色。
  1. class AnimatedContainerExample extends StatefulWidget {
  2.   @override
  3.   _AnimatedContainerExampleState createState() => _AnimatedContainerExampleState();
  4. }
  5. class _AnimatedContainerExampleState extends State<AnimatedContainerExample> {
  6.   double _width = 100;
  7.   Color _color = Colors.blue;
  8.   void _animateContainer() {
  9.     setState(() {
  10.       _width = _width == 100 ? 200 : 100;
  11.       _color = _color == Colors.blue ? Colors.red : Colors.blue;
  12.     });
  13.   }
  14.   @override
  15.   Widget build(BuildContext context) {
  16.     return GestureDetector(
  17.       onTap: _animateContainer,
  18.       child: AnimatedContainer(
  19.         width: _width,
  20.         height: 100,
  21.         color: _color,
  22.         duration: Duration(seconds: 1),
  23.         curve: Curves.easeInOut,
  24.       ),
  25.     );
  26.   }
  27. }
复制代码
2. 使用 Hero 动画

Hero 动画可以在页面切换时产生平滑的过渡效果。在不同页面中使用相同的 tag,可以让两个页面之间的共享元素过渡更加自然。
  1. class PageA extends StatelessWidget {
  2.   @override
  3.   Widget build(BuildContext context) {
  4.     return GestureDetector(
  5.       onTap: () {
  6.         Navigator.of(context).push(MaterialPageRoute(
  7.           builder: (context) => PageB(),
  8.         ));
  9.       },
  10.       child: Hero(
  11.         tag: 'avatar',
  12.         child: CircleAvatar(
  13.           radius: 50,
  14.           backgroundImage: AssetImage('assets/avatar.jpg'),
  15.         ),
  16.       ),
  17.     );
  18.   }
  19. }
  20. class PageB extends StatelessWidget {
  21.   @override
  22.   Widget build(BuildContext context) {
  23.     return Scaffold(
  24.       body: Center(
  25.         child: Hero(
  26.           tag: 'avatar',
  27.           child: CircleAvatar(
  28.             radius: 150,
  29.             backgroundImage: AssetImage('assets/avatar.jpg'),
  30.           ),
  31.         ),
  32.       ),
  33.     );
  34.   }
  35. }
复制代码
第三部分:自定义绘图和效果

1. 使用 CustomPaint 绘制图形

CustomPaint 允许你自定义绘制各种图形和效果。以下是一个简单的例子,绘制一个带边框的矩形。
  1. class CustomPaintExample extends StatelessWidget {
  2.   @override
  3.   Widget build(BuildContext context) {
  4.     return CustomPaint(
  5.       painter: RectanglePainter(),
  6.       child: Container(),
  7.     );
  8.   }
  9. }
  10. class RectanglePainter extends CustomPainter {
  11.   @override
  12.   void paint(Canvas canvas, Size size) {
  13.     final paint = Paint()
  14.       ..color = Colors.blue
  15.       ..style = PaintingStyle.stroke
  16.       ..strokeWidth = 2;
  17.     canvas.drawRect(Rect.fromLTWH(50, 50, 200, 100), paint);
  18.   }
  19.   @override
  20.   bool shouldRepaint(covariant CustomPainter oldDelegate) {
  21.     return false;
  22.   }
  23. }
复制代码
第四部分:Material 和 Cupertino 组件库

1. 使用 Material 组件

Material 组件库提供了一系列符合 Material Design 规范的 UI 组件。例如,AppBar、Button、Card 等。以下是一个使用 Card 的例子。
  1. Card(
  2.   elevation: 4,
  3.   child: ListTile(
  4.     leading: Icon(Icons.account_circle),
  5.     title: Text('John Doe'),
  6.     subtitle: Text('Software Engineer'),
  7.     trailing: Icon(Icons.more_vert),
  8.   ),
  9. )
复制代码
2. 使用 Cupertino 组件

Cupertino 组件库提供了 iOS 风格的 UI 组件,适用于 Flutter 应用在 iOS 平台上的开发。例如,CupertinoNavigationBar、CupertinoButton 等。
dart
Copy code
CupertinoNavigationBar(
middle: Text('Cupertino Example'),
trailing: CupertinoButton(
child: Text('Done'),
onPressed: () {},
),
)
第五部分:综合实例

以下是一个更加综合的例子,涵盖了之前提到的布局、动画、自定义绘图和 Material/Cupertino 组件库的知识点。
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/cupertino.dart';
  3. void main() {
  4.   runApp(MyApp());
  5. }
  6. class MyApp extends StatelessWidget {
  7.   @override
  8.   Widget build(BuildContext context) {
  9.     return MaterialApp(
  10.       home: ExampleScreen(),
  11.     );
  12.   }
  13. }
  14. class ExampleScreen extends StatelessWidget {
  15.   @override
  16.   Widget build(BuildContext context) {
  17.     return Scaffold(
  18.       appBar: AppBar(
  19.         title: Text('Advanced UI Example'),
  20.       ),
  21.       body: Padding(
  22.         padding: const EdgeInsets.all(16.0),
  23.         child: Column(
  24.           mainAxisAlignment: MainAxisAlignment.center,
  25.           children: [
  26.             AnimatedRotateExample(),
  27.             SizedBox(height: 20),
  28.             CustomPaintExample(),
  29.             SizedBox(height: 20),
  30.             PlatformWidgetsExample(),
  31.           ],
  32.         ),
  33.       ),
  34.     );
  35.   }
  36. }
  37. class AnimatedRotateExample extends StatefulWidget {
  38.   @override
  39.   _AnimatedRotateExampleState createState() => _AnimatedRotateExampleState();
  40. }
  41. class _AnimatedRotateExampleState extends State<AnimatedRotateExample> {
  42.   double _rotation = 0;
  43.   void _startRotation() {
  44.     Future.delayed(Duration(seconds: 1), () {
  45.       setState(() {
  46.         _rotation = 45;
  47.       });
  48.     });
  49.   }
  50.   @override
  51.   Widget build(BuildContext context) {
  52.     return Column(
  53.       children: [
  54.         GestureDetector(
  55.           onTap: () {
  56.             _startRotation();
  57.           },
  58.           child: AnimatedBuilder(
  59.             animation: Tween<double>(begin: 0, end: _rotation).animate(
  60.               CurvedAnimation(
  61.                 parent: ModalRoute.of(context)!.animation!,
  62.                 curve: Curves.easeInOut,
  63.               ),
  64.             ),
  65.             builder: (context, child) {
  66.               return Transform.rotate(
  67.                 angle: _rotation * 3.1416 / 180,
  68.                 child: child,
  69.               );
  70.             },
  71.             child: Container(
  72.               width: 100,
  73.               height: 100,
  74.               color: Colors.blue,
  75.               child: Icon(
  76.                 Icons.star,
  77.                 color: Colors.white,
  78.               ),
  79.             ),
  80.           ),
  81.         ),
  82.         Text('Tap to rotate'),
  83.       ],
  84.     );
  85.   }
  86. }
  87. class CustomPaintExample extends StatelessWidget {
  88.   @override
  89.   Widget build(BuildContext context) {
  90.     return CustomPaint(
  91.       painter: CirclePainter(),
  92.       child: Container(
  93.         width: 200,
  94.         height: 200,
  95.         alignment: Alignment.center,
  96.         child: Text(
  97.           'Custom Paint',
  98.           style: TextStyle(color: Colors.white, fontSize: 18),
  99.         ),
  100.       ),
  101.     );
  102.   }
  103. }
  104. class CirclePainter extends CustomPainter {
  105.   @override
  106.   void paint(Canvas canvas, Size size) {
  107.     final center = Offset(size.width / 2, size.height / 2);
  108.     final radius = size.width / 2;
  109.     final paint = Paint()
  110.       ..color = Colors.orange
  111.       ..style = PaintingStyle.fill;
  112.     canvas.drawCircle(center, radius, paint);
  113.   }
  114.   @override
  115.   bool shouldRepaint(CustomPainter oldDelegate) {
  116.     return false;
  117.   }
  118. }
  119. class PlatformWidgetsExample extends StatelessWidget {
  120.   @override
  121.   Widget build(BuildContext context) {
  122.     return Column(
  123.       children: [
  124.         Material(
  125.           elevation: 4,
  126.           child: ListTile(
  127.             leading: Icon(Icons.account_circle),
  128.             title: Text('John Doe'),
  129.             subtitle: Text('Software Engineer'),
  130.             trailing: Icon(Icons.more_vert),
  131.           ),
  132.         ),
  133.         SizedBox(height: 20),
  134.         CupertinoButton.filled(
  135.           child: Text('Explore'),
  136.           onPressed: () {},
  137.         ),
  138.       ],
  139.     );
  140.   }
  141. }
复制代码
这个示例演示了一个综合性的界面,包括点击旋转动画、自定义绘图和 Material/Cupertino 组件。你可以在此基础上进一步扩展和修改,以满足更复杂的 UI 设计需求。
总结

在本篇文章中,我们深入学习了 Flutter UI 的进阶技巧。我们了解了布局原理、动画实现、自定义绘图和效果,以及 Material 和 Cupertino 组件库的使用。通过实例演示,你将能够更加自信地构建复杂、令人印象深刻的用户界面。
希望这篇文章能够帮助你在 Flutter UI 进阶方面取得更大的进展。如果你有任何问题或需要进一步的指导,请随时向我询问。祝你在 Flutter 开发的道路上取得成功!

来源:https://www.cnblogs.com/depeng8899/p/17623108.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具