flutter中的布局和响应式app方法示例

作者:前端那些年 时间:2023-02-19 19:14:52 

flutter中的布局

flutter布局机制的核心是组件。在flutter中,几乎所有的东西都是组件,布局模型也不例外。图片,Icon, 文本等等,我们在flutter客户端中看到的所有内容都是组件。我们看不到的东西,比如:rows,columns,等等等等也都是组件。

我们将简单的组件组合在一起,构成复杂的组件。比如我们经常写的导航栏:

flutter中的布局和响应式app方法示例

他的布局可能是这样的:

flutter中的布局和响应式app方法示例

用树形图来表示是这样的:

flutter中的布局和响应式app方法示例

图中的大部分内容应该跟我们想象中的差不了多少,可能会有些人对Containter有些疑惑,Containter其实是一个容器组件,我们可以用它来控制一些子组件的展示,比如我们想要添加padding,margin,border,background- color等属性时,我们就可以用它来控制,用法和div基本一样。

(使用)放置一个组件

在flutter中如何使用组件呢?很简单。

比如,我想要一个居中的效果,那么我就使用Center组件;想要水平布局,我就使用row组件,想要垂直效果,就使用column组件。想要一个列表,那就listview组件,如此而已。

比如:创建一个文本。

Text('Hello World'),

比如:创建一个图片。

Image.asset(
 'images/lake.jpg',
 fit: BoxFit.cover,
)

比如:创建一个图标。

Icon(
 Icons.star,
 color: Colors.red[500],
)

app 本身就是个组件

试想一下我们平时搭建的vue或者react项目,其实他们本身就都是一个组件而已。

从bootstrap开始,或者讲的更透彻一些,从我们执行:

let app = new vue()  // let app =  createapp()
app.mount('#app', true)

mount执行完成后,全局项目的大组件就已经跑起来了。

然后我们又在各个模块中创建了页面,拆分了模块...

flutter也一样,如果你仔细对比一下vue,或者react项目的入口文件和flutter项目入口文件的区别:

import 'package:flutter/material.dart';
import 'mine.dart';
import './yours.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'),
     routes: {'/mine': (context) => Mine(), '/yours': (context) => Yours()},
   );
 }
}

发现了吗,其实是一样的套路,实例化了一个全局的app,一个全局的组件。

Material apps 和 Non-Material apps

对于Material app,我们可以使用app本身自带的一些组件,比如:Scaffold提供了默认的顶部导航,底部导航,抽屉等组件,开发起来非常方便。比如:

class MyApp extends StatelessWidget {
 const MyApp({super.key});
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Flutter layout demo',
     home: Scaffold(
       appBar: AppBar(
         title: const Text('Flutter layout demo'),
       ),
       body: const Center(
         child: Text('Hello World'),
       ),
     ),
   );
 }
}

而Non-Material apps 则没有提供这些组件,我们想要实现那些东西,都需要我们自己动手去封装。比如:

class MyApp extends StatelessWidget {
 const MyApp({super.key});
 @override
 Widget build(BuildContext context) {
   return Container(
     decoration: const BoxDecoration(color: Colors.white),
     child: const Center(
       child: Text(
         'Hello World',
         textDirection: TextDirection.ltr,
         style: TextStyle(
           fontSize: 32,
           color: Colors.black87,
         ),
       ),
     ),
   );
 }
}

自适应和响应式

flutter的一个主要目的是为我们提供一个组件库,让我们可以很快的进行开发,并且开发出来的应用可以运行在多个平台上。这意味着我们的应用程序在不同尺寸的屏幕上,手机,手表,或者显示器都有可能。

所以,我们的应用应该是响应式的,或者叫自适应。

自适应和响应式听起来很相似,但是它们是一回事儿吗?也许未必如此。

自适应和响应式其实是两个维度的东西。我们可以开发一个没有响应式的自适应程序,也可以开发一个没有自适应的响应式程序。也许有些人会很疑惑,没有响应式的自适应程序,比如我要兼容三个设备,那么我写三套代码去兼容它们,这就是非响应式的自适应程序。

当然,我们也可以开发出既是自适应,又是响应式的程序。

什么是响应式?通常情况下,自适应的应用程序的布局可以根据屏幕大小进行调整。比如用户调整了窗口大小,旋转了设备方向,那么就会重新进行布局。这一点在应用运行在不同的设备上时,显得尤为重要。

什么是自适应?应用程序在不同的设备上运行,我们需要处理鼠标,键盘输入以及触摸输入等功能,需要我们对程序的视觉效果,组件的工作方式,API在各个平台上的兼容性有一定的了解。

如此看来,响应式似乎侧重于布局,而自适应则既要考虑布局,又要兼顾功能。

flutter实现响应式的方法

使用flutter我们可以非常方便的开发出响应式或自适应的app。有两种可行的方案:

一种是利用LayoutBuilder这个类。通过它的builder属性,我们可以获取到BoxConstraints对象,检查容器的约束性来决定展示什么。比如:如果我们的maxWidth大于我们的屏幕宽度的临界点,就返回一个包含列表的Scaffold对象。如果小于屏幕的临界点,就基别的因素进行布局。

另外一种是使用媒体查询技术MediaQuery.of()。它可以获取我们当前应用的size,orientation等信息,我们可以根据获取的信息作出一些有利于我们应用展示效果的决策。

其他的可以用来创建响应式ui的组件有,比如:

  • AspectRatio

  • CustomSingleChildLayout

  • CustomMultiChildLayout

  • FittedBox

  • FractionallySizedBox

  • LayoutBuilder

  • MediaQuery

  • MediaQueryData

  • OrientationBuilder

这些都可以用来开发响应式的app应用。

小结

本文简单介绍一下flutter如何开发响应式app,更多关于flutter布局响应式app的资料请关注脚本之家其它相关文章!

来源:https://juejin.cn/post/7174078317539098654

标签:flutter,布局,响应式,app
0
投稿

猜你喜欢

  • 详解java 中泛型中的类型擦除和桥方法

    2021-07-10 23:55:08
  • Android如何自定义按钮效果

    2022-08-14 13:11:53
  • Java 深拷贝与浅拷贝的分析

    2023-07-30 14:13:13
  • Spring实战之@Autowire注解用法详解

    2021-11-17 20:37:19
  • Android自定义View实现等级滑动条的实例

    2023-12-08 19:57:53
  • Android 根据手势顶部View自动展示与隐藏效果

    2022-01-11 07:30:20
  • C#并行编程之Task任务

    2023-05-30 16:54:41
  • StringBuilder为什么线程不安全深入讲解

    2023-01-24 01:52:55
  • 解答为什么 Java 线程没有Running状态

    2021-08-25 13:10:33
  • java 动态生成SQL的实例讲解

    2021-05-25 18:26:06
  • C#中标准的IDispose模式代码详解

    2022-03-27 01:40:05
  • C# ref and out的使用小结

    2021-12-19 22:35:40
  • 移动开发Spring Boot外置tomcat教程及解决方法

    2023-08-25 11:47:33
  • SpringBoot实现配置文件的替换

    2023-11-21 22:27:16
  • Spring 代理 Bean 获取不到原始 Bean 对象注解解决方法

    2022-10-31 17:06:08
  • Java动态规划之硬币找零问题实现代码

    2023-01-23 20:37:38
  • Java Socket编程(四) 重复和并发服务器

    2022-06-29 07:07:06
  • 浅谈java的守护线程与非守护线程

    2023-11-25 06:50:23
  • java 流与 byte[] 的互转操作

    2023-06-26 11:25:46
  • C#和Java有什么区别和联系

    2022-01-02 04:33:26
  • asp之家 软件编程 m.aspxhome.com