使用Flutter实现一个走马灯布局的示例代码
2020年02月13日
作者:佚名
走马灯是一种常见的效果,本文讲一下如何用 PageView 在 Flutter 里实现一个走马灯,效果如下,当前页面的高度比其它页面高,切换页面的时候有一个高度变化的动画。实现这样的效果主要用到的是 PageView.builder 部件。
添加内容
然后给 AnimatedContainer 添加每一项的内容
child: Stack( fit: StackFit.expand,children: <Widget>[ ClipRRect( borderRadius: BorderRadius.all( Radius.circular(12.0),child: Image.network( heroes[index].image,fit: BoxFit.cover,Align( alignment: Alignment.bottomCenter,child: Row( children: <Widget>[ Expanded( child: Container( padding: EdgeInsets.all(12.0),decoration: BoxDecoration( color: Colors.black26,borderRadius: BorderRadius.only( bottomRight: Radius.circular(12.0),bottomLeft: Radius.circular(12.0),child: Text( heroes[index].title,textAlign: TextAlign.center,style: TextStyle( fontSize: 20.0,fontWeight: FontWeight.bold,color: Colors.white,) ],
实现指示器
然后实现页面的指示器,创建一个 PageIndicator 部件,需要传入 pageCount 表示总页数,以及 currentIndex 表示当前显示的页数索引。把所有指示器放在一个 Row 部件里,判断当前指示器的 index 是否为正在显示页面的 index ,是的话显示较深的颜色。
class PageIndicator extends StatelessWidget { final int pageCount; final int currentIndex; const PageIndicator(this.currentIndex,this.pageCount); Widget _indicator(bool isActive) { return Container( width: 6.0,height: 6.0,margin: EdgeInsets.symmetric(horizontal: 3.0),decoration: BoxDecoration( color: isActive ? Color(0xff666a84) : Color(0xffb9bcca),shape: BoxShape.circle,boxShadow: [ BoxShadow( color: Colors.black12,offset: Offset(0.0,3.0),blurRadius: 3.0,); } List<Widget> _buildIndicators() { List<Widget> indicators = []; for (int i = 0; i < pageCount; i++) { indicators.add(i == currentIndex ? _indicator(true) : _indicator(false)); } return indicators; } @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center,children: _buildIndicators(),); } }
添加 PageIndicator 到 SizedBox 下面
封装 Carousel
最后的最后优化一下代码,把部件封装一下,让它成为一个单独的部件,创建一个 Carousel 部件,对外暴露 items 和 height 两个属性,分别配置数据和高度。
class Carousel extends StatefulWidget { final List items; final double height; const Carousel({ @required this.items,@required this.height,}); @override _CarouselState createState() => _CarouselState(); } class _CarouselState extends State<Carousel> { int _pageIndex = 0; PageController _pageController; Widget _buildItem(activeIndex,index) { final items = widget.items; return Center( child: AnimatedContainer( curve: Curves.easeInOut,decoration: BoxDecoration( color: items[index].color,child: Stack( fit: StackFit.expand,children: <Widget>[ ClipRRect( borderRadius: BorderRadius.all( Radius.circular(12.0),child: Image.network( items[index].image,Align( alignment: Alignment.bottomCenter,child: Row( children: <Widget>[ Expanded( child: Container( padding: EdgeInsets.all(12.0),decoration: BoxDecoration( color: Colors.black26,borderRadius: BorderRadius.only( bottomRight: Radius.circular(12.0),child: Text( items[index].title,style: TextStyle( fontSize: 20.0,) ],); } @override void initState() { super.initState(); _pageController = PageController( initialPage: 0,); } @override Widget build(BuildContext context) { return Column( children: <Widget>[ Container( height: widget.height,child: PageView.builder( pageSnapping: true,itemCount: heroes.length,onPageChanged: (int index) { setState(() { _pageIndex = index; }); },index); },PageIndicator(_pageIndex,widget.items.length),); } }
之后在 IndexPage 部件里就只用实例化一个 Carousel 了,同时由于 IndexPage 不用管理部件状态了,可以将它变成 StatelessWidget 。
完整代码
import 'package:flutter/material.dart'; class Hero { final Color color; final String image; final String title; Hero({ @required this.color,@required this.image,@required this.title,}); } List heroes = [ Hero( color: Color(0xFF86F3FB),image: "https://game.gtimg.cn/images/lol/act/img/skin/big22009.jpg",title: '寒冰射手-艾希',Hero( color: Color(0xFF7D6588),image: "https://game.gtimg.cn/images/lol/act/img/skin/big39006.jpg",title: '刀锋舞者-艾瑞莉娅',Hero( color: Color(0xFF4C314D),image: "https://game.gtimg.cn/images/lol/act/img/skin/big103015.jpg",title: '九尾妖狐-阿狸',]; class Carousel extends StatefulWidget { final List items; final double height; const Carousel({ @required this.items,); } } class PageIndicator extends StatelessWidget { final int currentIndex; final int pageCount; const PageIndicator(this.currentIndex,); } } class IndexPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 0.0,body: Carousel( height: 540,items: heroes,); } }
至此,整个布局就完成了! :sunglasses:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
以上是来客网为你收集整理的使用Flutter实现一个走马灯布局的示例代码全部内容,希望文章能够帮你解决使用Flutter实现一个走马灯布局的示例代码所遇到的程序开发问题。
如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。