Dart & Flutter 開發技巧 8-14
1929
2025-04-03
這里是堅果前端小課堂,歡迎關注公眾號“堅果前端”,領取flutter電子書以及源碼
本教程將向您展示如何在 flutter 中設置背景圖像。
在 Flutter 應用程序中設置背景圖像的常用方法是使用DecorationImage. 以下示例包括如何設置Fit 模式、透明度以及在顯示鍵盤時防止圖像變化。
設置背景圖像使用 DecorationImage
您可能已經熟悉Container小部件。Container 的構造函數有一個名為decoration的參數,用于在 child 后面繪制裝飾。對于該參數,您需要傳遞一個Decoration值。Flutter 中有一些Decoration類。其中一些,例如BoxDecorationand ShapeDecoration,允許您傳遞類型為image的參數DecorationImage。
該DecorationImage構造函數需要你傳遞一個參數,其名稱也為image,為此您需要傳遞一個 ImageProvider 作為值。本教程以 NetworkImage 為例。但是您也可以使用其他 ImageProvider,例如 MemoryImage、FileImage,或從資產加載圖像。
static const String imageUrl = 'https://mocah.org/thumbs/268085-wallpaper-1080-2400.jpg'; static const Widget appName = const Text( '堅果前端', style: const TextStyle( color: Colors.white, fontSize: 48, fontWeight: FontWeight.bold), ); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('堅果前端'), ), body: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( image: DecorationImage( image: NetworkImage(imageUrl), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ appName, ], ), ), ); }
輸出:
設置Fit 模式
如果圖像不適合屏幕,您可能需要調整圖像應如何嵌入到可用空間中。它可以通過傳遞一個BoxFit枚舉值作為fit參數來完成。可能的值為:
fill:設置源填充目標框。它可能會扭曲源的縱橫比。
contain:在目標框內將源設置為盡可能大。
cover:將源設置為盡可能小,同時仍覆蓋整個目標框。
fitWidth: 設置源的寬度以匹配目標框的寬度。它可能會導致源垂直溢出目標框。
fitHeight: 設置源的高度以匹配目標框的寬度。它可能會導致源水平溢出目標框。
none: 對齊目標框內的源并丟棄框外的任何部分..
scaleDown:在目標框內對齊源并在必要時縮小源以適合目標框。
Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fitWidth, image: NetworkImage(imageUrl), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ appName, ], ), ),
設置圖像透明度/不透明度
要設置背景圖像的透明度或不透明度,您可以傳遞colorFilter參數。在下面的示例中,我們創建了ColorFilter不透明度為 0.2 的 ?;旌夏J皆O置為dstATop,將目標圖像(透明濾鏡)合成到源圖像(背景圖像)重疊的位置。
Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fitWidth, colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop), image: NetworkImage(imageUrl), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ appName, ], ), ),
輸出:
顯示鍵盤時防止調整大小
在移動設備上,當用戶與文本字段交互時,通常會顯示屏幕鍵盤。顯示鍵盤時,應用程序內容的屏幕區域變小。它還會影響背景圖像的渲染方式,因為圖像必須適合較小的空間。
例如,有一個TextField小部件
static const Widget textField = const TextField( decoration: InputDecoration( labelText: 'Name', hintText: 'Enter your name', hintStyle: const TextStyle(color: Colors.white), ) );
如果TextField小部件是當前焦點節點,則會顯示屏幕鍵盤。正如您在下面的輸出中看到的,背景圖像受到影響。在這種情況下,由于fit模式為fitWidth,圖像被向上推以使用較小的可用高度空間進行調整。
Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fitWidth, image: NetworkImage(imageUrl), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ appName, textField, ], ), ),
輸出:
如果你想讓背景圖像不受鍵盤存在的影響,你可以將resizeToAvoidBottomInset參數傳遞給的構造函數Scaffold并將值設置為false。該參數的值默認為true,這會導致調整小部件的大小,使其不與屏幕鍵盤重疊。``
Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( title: const Text('堅果前端'), ), body: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fitWidth,\ image: NetworkImage(imageUrl),\ ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ appName, textField, ], ), ), )
輸出:
但是,如果內容不適合可用空間,您將遇到另一個問題。正如您在上面的輸出中看到的那樣,當顯示鍵盤時,部分內容是不可見的。一種可能的解決方法是將 Scaffold 包裹在帶有背景圖像的 Container 中。然后,您需要將內容(可以滾動)放在 Scaffold 下,必要時將其包裹在 SingleChildScrollView 中。
return Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fitWidth, image: NetworkImage(imageUrl), ), ), child: Scaffold( backgroundColor: Colors.transparent, // resizeToAvoidBottomInset: false, appBar: AppBar( title: const Text('堅果前端'), ), body: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ appName, appName, appName, textField, appName, appName, appName, ], ), ), ), );
輸出:
完整代碼
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: '堅果前端', home: BackgroundImageExample(), debugShowCheckedModeBanner: false, ); } } class BackgroundImageExample extends StatelessWidget { static const String imageUrl = 'https://mocah.org/thumbs/268085-wallpaper-1080-2400.jpg'; static const Widget appName = const Text( '堅果前端', style: const TextStyle( color: Colors.white, fontSize: 48, fontWeight: FontWeight.bold), ); static const Widget textField = const TextField( decoration: InputDecoration( labelText: 'Name', hintText: 'Enter your name', hintStyle: const TextStyle(color: Colors.white), )); @override Widget build(BuildContext context) { // 1. Example without prevent image resizing (can be used if the application never show the on-screen keyboard). // return Scaffold( // // resizeToAvoidBottomInset: false, // appBar: AppBar( // title: const Text('堅果前端'), // ), // body: Container( // width: double.infinity, // height: double.infinity, // decoration: BoxDecoration( // image: DecorationImage( // fit: BoxFit.fitWidth, // // colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop), // image: NetworkImage(imageUrl), // // image: Image.asset('assets/images/pikachu.png').image, // ), // ), // child: Column( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // appName, // textField, // ], // ), // ), // ); // 2. Example that prevents image resizing when the keyboard is shown. return Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fitWidth, // colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop), image: NetworkImage(imageUrl), // image: Image.asset('assets/images/pikachu.png').image, ), ), child: Scaffold( backgroundColor: Colors.transparent, // resizeToAvoidBottomInset: false, appBar: AppBar( title: const Text('堅果前端'), ), body: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ appName, appName, appName, textField, appName, appName, appName, ], ), ), ), ); } }
概括
要設置背景圖像,您可以使用Container小部件并傳遞Decoration包含圖像的對象。對于圖像源,您需要創建一個DecorationImage并將其傳遞給Decoration. 還可以定義圖像應如何刻入可用空間并設置圖像的不透明度。如果應用程序包含可能觸發屏幕鍵盤的文本字段,您還需要處理如上所示的情況。
Android Dart Flutter
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。