<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在 Flutter 我們只需要掌握一些 Widget 即可,實際的開發過程中,我們也只需要在合適的地方使用它們即可。
第一個 Widget 即是 MediaQuery,通過它可以直接獲得螢幕的大小(寬度 / 高度)和方向(縱向 / 橫向)。
cclass HomePage extends StatelessWidget { @override Widget build(BuildContext context) { Size screenSize = MediaQuery.of(context).size; Orientation orientation = MediaQuery.of(context).orientation; return Scaffold( body: Container( color: CustomColors.android, child: Center( child: Text( 'Viewnn' + '[MediaQuery width]: ${screenSize.width.toStringAsFixed(2)}nn' + '[MediaQuery orientation]: $orientation', style: TextStyle(color: Colors.white, fontSize: 18), ), ), ), ); } }
使用 LayoutBuilder 元件,可以獲得一個 BoxConstraints 物件,通過該物件我們就可以拿到 Widget 的 maxWidth(最大寬度) 和maxHeight(最大高度)
MediaQuery 和 LayoutBuilder 的區別在在於,MediaQuery 得到的是整個螢幕的寬高,而 LayoutBuilder 得到的是特定元件的最大高度和寬度。
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { Size screenSize = MediaQuery.of(context).size; return Scaffold( body: Row( children: [ Expanded( flex: 2, child: LayoutBuilder( builder: (context, constraints) => Container( color: CustomColors.android, child: Center( child: Text( 'View 1nn' + '[MediaQuery]:n ${screenSize.width.toStringAsFixed(2)}nn' + '[LayoutBuilder]:n${constraints.maxWidth.toStringAsFixed(2)}', style: TextStyle(color: Colors.white, fontSize: 18), ), ), ), ), ), Expanded( flex: 3, child: LayoutBuilder( builder: (context, constraints) => Container( color: Colors.white, child: Center( child: Text( 'View 2nn' + '[MediaQuery]:n ${screenSize.width.toStringAsFixed(2)}nn' + '[LayoutBuilder]:n${constraints.maxWidth.toStringAsFixed(2)}', style: TextStyle(color: CustomColors.android, fontSize: 18), ), ), ), ), ), ], ), ); } }
要確定當前 Widget 的方向,可以使用 OrientationBuilder 元件。這裡的方向與 MediaQuery 提供的裝置方向不同。
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { Orientation deviceOrientation = MediaQuery.of(context).orientation; return Scaffold( body: Column( children: [ Expanded( flex: 2, child: Container( color: CustomColors.android, child: OrientationBuilder( builder: (context, orientation) => Center( child: Text( 'View 1nn' + '[MediaQuery orientation]:n$deviceOrientationnn' + '[OrientationBuilder]:n$orientation', style: TextStyle(color: Colors.white, fontSize: 18), ), ), ), ), ), Expanded( flex: 3, child: OrientationBuilder( builder: (context, orientation) => Container( color: Colors.white, child: Center( child: Text( 'View 2nn' + '[MediaQuery orientation]:n$deviceOrientationnn' + '[OrientationBuilder]:n$orientation', style: TextStyle(color: CustomColors.android, fontSize: 18), ), ), ), ), ), ], ), ); } }
Expanded 和 Flexible 這兩個元件可以和 Column/Row 搭配使用,來實現非常完美的自適應效果。Expanded 可以用來拓展 Row, 、Column 和 Flex,從而讓子元件填充可用空間,Flexible 功能類似但並不一定能填充全部可用空間。
下面這個例子演示了混合使用 Expanded 和 Flexible 的各種方式:
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Column( children: [ Row( children: [ ExpandedWidget(), FlexibleWidget(), ], ), Row( children: [ ExpandedWidget(), ExpandedWidget(), ], ), Row( children: [ FlexibleWidget(), FlexibleWidget(), ], ), Row( children: [ FlexibleWidget(), ExpandedWidget(), ], ), ], ), ), ); } } class ExpandedWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Expanded( child: Container( decoration: BoxDecoration( color: CustomColors.android, border: Border.all(color: Colors.white), ), child: Padding( padding: const EdgeInsets.all(16.0), child: Text( 'Expanded', style: TextStyle(color: Colors.white, fontSize: 24), ), ), ), ); } } class FlexibleWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Flexible( child: Container( decoration: BoxDecoration( color: CustomColors.androidAccent, border: Border.all(color: Colors.white), ), child: Padding( padding: const EdgeInsets.all(16.0), child: Text( 'Flexible', style: TextStyle(color: CustomColors.android, fontSize: 24), ), ), ), ); } }
FractionallySizedBox 元件可以使子元件填充部分可用空間,該特性在 Expanded 或 Flexible 中特別有用。
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ FractionallySizedWidget(widthFactor: 0.4), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ FractionallySizedWidget(widthFactor: 0.6), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ FractionallySizedWidget(widthFactor: 0.8), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ FractionallySizedWidget(widthFactor: 1.0), ], ), ], ), ), ); } } class FractionallySizedWidget extends StatelessWidget { final double widthFactor; FractionallySizedWidget({@required this.widthFactor}); @override Widget build(BuildContext context) { return Expanded( child: FractionallySizedBox( alignment: Alignment.centerLeft, widthFactor: widthFactor, child: Container( decoration: BoxDecoration( color: CustomColors.android, border: Border.all(color: Colors.white), ), child: Padding( padding: const EdgeInsets.all(16.0), child: Text( '${widthFactor * 100}%', style: TextStyle(color: Colors.white, fontSize: 24), ), ), ), ), ); } }
AspectRatio 元件可以直接指定子元件的固定寬高比例,使用時,我們可以使用佈局約束的最大寬度,並給定一個寬高比自適應其高度
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Column( children: [ AspectRatioWidget(ratio: '16 / 9'), AspectRatioWidget(ratio: '3 / 2'), ], ), ), ); } } class AspectRatioWidget extends StatelessWidget { final String ratio; AspectRatioWidget({@required this.ratio}); @override Widget build(BuildContext context) { return AspectRatio( aspectRatio: Fraction.fromString(ratio).toDouble(), child: Container( decoration: BoxDecoration( color: CustomColors.android, border: Border.all(color: Colors.white), ), child: Padding( padding: const EdgeInsets.all(16.0), child: Center( child: Text( 'AspectRatio - $ratio', style: TextStyle(color: Colors.white, fontSize: 24), ), ), ), ), ); } }
到此這篇關於Flutter元件適配方法實現詳解的文章就介紹到這了,更多相關Flutter元件適配內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45