MediaQuery
主要原理是通过 MediaQuery 拿到上下文(就是当前设备的信息),然后动态的配置宽度和高度来达到自适应。
使用 MediaQuery:Flutter 的 MediaQuery 类提供了设备的屏幕信息,如屏幕宽度、高度和方向等。你可以使用 MediaQuery.of(context) 来获取当前上下文中的 MediaQueryData 对象,并根据需要调整布局。
double screenWidth = MediaQuery.of(context).size.width; double screenHeight = MediaQuery.of(context).size.height;
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { // 获取设备的屏幕信息 final mediaQuery = MediaQuery.of(context); return MaterialApp( title: 'Responsive Layout', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: Text('Responsive Layout'), ), body: Container( // 使用 mediaQuery 获取屏幕宽度和高度 width: mediaQuery.size.width, height: mediaQuery.size.height, child: Column( children: [ Text( '当前设备宽度: ${mediaQuery.size.width}', style: TextStyle(fontSize: 20), ), Text( '当前设备宽度: ${mediaQuery.size.width}', style: TextStyle(fontSize: 20), ), ], ), ), ), ); } }
使用注意:
- 在使用 MediaQuery 之前,确保你的组件树中有一个 MaterialApp 或 WidgetsApp,以便获取正确的上下文。
- MediaQuery 是一个全局的对象,可以在任何地方获取。但为了避免重复获取,通常会在 build 方法中获取一次,并将其存储在变量中供后续使用。
- MediaQuery 提供了许多其他属性,如设备方向、像素密度等,你可以根据实际需求使用这些属性来调整布局。
LayoutBuilder
使用 LayoutBuilder:Flutter 的 LayoutBuilder 组件可以根据父容器的约束条件来构建自适应布局。通过 builder 回调函数的参数constraints
来拿到父容易得宽度和高度来 达到自适应。
LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { // 获取父容器的宽度和高度 var screenWidth = constraints.maxWidth; var screenHeight = constraints.maxHeight; } )
Widget build(BuildContext context) { // 获取设备的屏幕信息 final mediaQuery = MediaQuery.of(context); return Container(child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { // 获取父容器的宽度和高度 var screenWidth = constraints.maxWidth; var screenHeight = constraints.maxHeight; return Container( child: Column( children: [ Text('constraints-当前设备的宽度: ${screenWidth}', style: TextStyle(color: Colors.red, fontSize: 22)), Text('constraints-当前设备的高度: ${screenHeight}', style: TextStyle(color: Colors.red, fontSize: 22)), ], )); })
使用注意:
- LayoutBuilder 必须作为父容器的直接子组件,以便能够获取到正确的约束条件。
- 在 builder 回调函数中,可以根据约束条件 constraints 来动态调整子组件的布局。
- 父容器的约束条件 constraints 提供了许多属性,如最小宽度、最大宽度、最小高度、最大高度等,你可以根据实际需求使用这些属性来进行布局调整。
- 使用 Flex 和 Expanded:Flutter 的 Flex 和 Expanded 组件可用于创建弹性布局,使子组件能够根据可用空间自动调整大小。
Row( children: [ Expanded( flex: 1, child: Container(), ), Expanded( flex: 2, child: Container(), ), ], )
- 使用 Wrap 和 Flow:Flutter 的 Wrap 和 Flow 组件可用于创建流式布局,使子组件能够自动换行并适应可用空间。
Wrap( children: [ Container(), Container(), Container(), ], )
- 使用约束布局:Flutter 的 ConstrainedBox 和 AspectRatio 组件可用于设置子组件的最小或最大尺寸,并保持宽高比例。
ConstrainedBox( constraints: BoxConstraints( minWidth: 100, minHeight: 100, maxWidth: 200, maxHeight: 200, ), child: Container(), )
这些是构建自适应布局的常用方法。你可以根据具体需求选择合适的方法或组合多种方法来实现灵活且响应式的布局。