Flutter佈局錦囊---輪播圖片與滑塊
阿新 • • 發佈:2019-01-05
設計給的效果如下:
拿到設計後,先把整體拆分成幾個部分:
- “運營位”,可以通過左右滑動來切換圖片。
- “進度條”,顯示“運營位”當前位置的進度條。
然後就可以開始進行編碼了。
第1步:繪製元件樹
第2步:實現“運營位”
Flutter沒有直接提供可以通過左右滑動來切換圖片的元件,不過你可以在Flutter第三方包和外掛倉庫中找到解決方案,carousel_slider包是一個輪播(CarouselSlider
)元件,支援無限滾動和自定義子元件。
import 'package:flutter/material.dart';
// 正常使用carousel_slider包的話,應該是下面這樣來引用的:
// import 'package:carousel_slider/carousel_slider.dart';
// 下面這樣寫是因為我把carousel_slider包的程式碼複製下來,
// 研究了一下實現細節,然後放在了`../common/carousel_slider.dart`目錄下。
import '../common/carousel_slider.dart';
/// 運營點陣圖片列表。
final List<String> imgList = [
'assets/img_login_01.png',
'assets/img_login_02.png',
'assets/img_login_03.png' ,
];
/// 用給定的處理函式(`handler`)處理給定的列表資料(`list`),
/// 返回處理結果列表(`result`)。
List<T> worker<T>(List list, Function handler) {
List<T> result = [];
for (var i = 0; i < list.length; i++) {
result.add(handler(i, list[i]));
}
return result;
}
class CarouselWithIndicator extends StatefulWidget {
@override
_CarouselWithIndicatorState createState() => _CarouselWithIndicatorState();
}
class _CarouselWithIndicatorState extends State<CarouselWithIndicator> {
/// 當前頁面的索引。
int _current = 0;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
// carousel_slider包裡的輪播元件(`CarouselSlider`)元件。
CarouselSlider(
// 使用自定義的工人`agent`方法生成一個容器元件列表。
items: worker<Widget>(imgList, (index, i) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
// 裝飾圖片(`DecorationImage`)類的圖片(`image`)屬性,
// 將影象繪製成裝飾。
// 通常通過資產圖片(`AssetImage`)使用隨應用程式一起提供的影象,
// 或通過網路影象(`NetworkImage`)使用從網路獲取的影象。
image: AssetImage(i),
// 適應屬性,如何在框裡展示影象。
// https://docs.flutter.io/flutter/painting/BoxFit-class.html
fit: BoxFit.cover
)
),
);
}),
// 是否自動播放,預設為`false`。
autoPlay: false,
// 當前頁面在視窗中佔用的空間,預設為`0.8`。
viewportFraction: 1.0,
// 寬高比例,預設為`16/9`。
aspectRatio: 3/2,
// 切換時當前頁面逐漸變小,新頁面逐漸變大直至完全替代當前頁面,
// 預設為`true`。
distortion: false,
// 視窗中頁面更新時的回撥函式。
updateCallback: (index) {
setState(() {
_current = index;
});
},
),
// TODO: 第3步:實現“進度條”
],
);
}
}
第3步:實現“進度條”
Flutter直接提供的線性進度指示器(LinearProgressIndicator
)元件可以輕鬆的實現“進度條”部分。但是“進度條”的寬度是沒有給確定值的,所以你需要擴充套件(Expanded
)元件,用於展開行、垂直或柔性(Flex
)元件的子元件,可以實現靈活的佈局。
// TODO: 第3步:實現“進度條”
Row(
children: <Widget>[
// 左邊的空白部分,設定佔2個彈性因子,高度為30.0以撐起“進度條”的高度。
Expanded(
// 柔性屬性,用於此子元件的彈性因子。
flex: 2,
child: SizedBox(height: 30.0),
),
// 中間的“進度條”,設定佔1個彈性因子。
Expanded(
flex: 1,
child: SizedBox(
height: 4.0,
// 線性進度指示器(`LinearProgressIndicator`)元件,
// 顯示沿線的進度,也稱為進度條。
child: LinearProgressIndicator(
// 背景顏色(`backgroundColor `)屬性,進度指示器的背景顏色。
backgroundColor: const Color(0xFFE1E1E1),
// 值顏色(`valueColor`)屬性,指標的顏色是動畫的值。
valueColor: AlwaysStoppedAnimation(Color(0xFF414141)),
// 值(`value `)屬性,0.0~1.0對應於進度條當前進度。
value: (_current + 1) / imgList.length,
),
),
),
// 右邊的空白部分,設定佔2個彈性因子,高度為30.0以撐起“進度條”的高度。
Expanded(
flex: 2,
child: SizedBox(height: 30.0),
),
],
),