flutter_url_launcher轮播图banner编写(自定义可随意在任何地方添加和删除)
  kXQGibE6SARU 2023年11月13日 25 0


自动无限循环,可以手动拖拽,指示器显示

flutter_url_launcher轮播图banner编写(自定义可随意在任何地方添加和删除)_ide


首页代码,将轮播图自定义出来一个控件,直接可以添加和删除

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('首页')
),
body: Column(
children: <Widget>[
Stack(//帧布局
//alignment: const FractionalOffset(0.9, 0.1),//方法一
children: <Widget>[
Pagination(),//轮播图 banner
Positioned(//方法二
top: 10.0,
left: 0.0,
// child: DisclaimerMsg(key:key,pWidget:this)
child:Text('banner学习',) //悬浮在banner上方
),
]),
SizedBox(height: 1, child:Container(color: Theme.of(context).primaryColor)),
SizedBox(height: 10),
],
),
);

}

轮播图组件代码

import 'package:flutter/material.dart';
import './home_banner.dart';
import './story.dart';
import 'package:url_launcher/url_launcher.dart';
/// 轮播图组件 可以直接引入
class Pagination extends StatelessWidget {
static final String routeName = '/material/page-selector';
static final List<Icon> icons = <Icon>[
const Icon(Icons.event, semanticLabel: 'Event'),
const Icon(Icons.home, semanticLabel: 'Home'),
const Icon(Icons.android, semanticLabel: 'Android'),
const Icon(Icons.alarm, semanticLabel: 'Alarm'),
const Icon(Icons.face, semanticLabel: 'Face'),
const Icon(Icons.language, semanticLabel: 'Language'),
];

final List<dynamic> arr = [
{'image': 'https://pics2.baidu.com/feed/8d5494eef01f3a291779e03320581f355d607c1f.jpeg', 'type': 0, 'id': 9695909, 'url': 'https://www.zhihu.com/question/294145797/answer/551162834', 'title': '中国女足收获四国赛冠军!但王霜太累了,何时能歇歇?'},
{'image': 'https://pics5.baidu.com/feed/a9d3fd1f4134970a1ca8142320b772cca6865d60.jpeg', 'type': 0, 'id': 9695859, 'url': 'https://zhuanlan.zhihu.com/p/51696594', 'title': '郑州火车站加开40趟临时列车 应对清明假期返程高峰'},
{'image': 'https://pics4.baidu.com/feed/6c224f4a20a44623d9a783e62d5fd10a0df3d743.jpeg', 'type': 0, 'id': 96956491409, 'url':'https://zhuanlan.zhihu.com/p/53497167','title': '凉山火灾复燃面积约7公顷 扑火人员已撤至安全地带'},
{'image': 'https://pics5.baidu.com/feed/d01373f082025aaf986c179a4e900860024f1a82.jpeg', 'type': 0, 'id': 9695816, 'url': 'https://mp.weixin.qq.com/s?__biz=MzAwODY4OTk2Mg==&mid=2652048101&idx=1&sn=20296088e4bd8ca33c5c9991167d9f7d&chksm=808caaa0b7fb23b65c0e5806209f8d86da6732f3a00a70353f3606018339518b0a8656f14dc5&mpsshare=1&scene=2&srcid=0106SZapVysZdIS6Oc5AhNH6&from=timeline&ascene=2&devicetype=android-27&version=27000038&nettype=WIFI&abtest_cookie=BQABAAgACgALABMAFAAFAJ2GHgAjlx4AV5keAJuZHgCcmR4AAAA%3D&lang=zh_CN&pass_ticket=4K1%2FUpsxP4suPj2iubR17wbAP7r9LW9iYrPAC2dppTqv7j7JO5FWMXtcKeBRxueV&wx_header=1', 'title': '高雄飞往香港客机迫降 初步判断:机械故障并非鸟击'}
];

void _launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}

List<Widget> _pageSelector(BuildContext context) {
List<Widget> list = [];
List<StoryModel> bannerStories = [];
/// super.initState();
arr.forEach((item) {
bannerStories.add(StoryModel.fromJson(item));
});


if (arr.length > 0) {
list.add(HomeBanner(bannerStories, (story) {
_launchURL('${story.url}');
}));
}
return list;
}

@override
Widget build(BuildContext context) {
return
Column(
key:Key('__header__'),
//physics: AlwaysScrollableScrollPhysics(),
//padding: EdgeInsets.only(),
children: _pageSelector(context)
);
}
}

轮播图事件控制,拖拽,点击,标题显示,指示器等

import 'dart:async';
import 'package:flutter/material.dart';
import './story.dart';

class HomeBanner extends StatefulWidget {
final List<StoryModel> bannerStories;
final OnTapBannerItem onTap;

HomeBanner(this.bannerStories, this.onTap, {Key key})
:super(key: key);

@override
State<StatefulWidget> createState() {
return _BannerState();
}
}

class _BannerState extends State<HomeBanner> {
int virtualIndex = 0;
int realIndex = 1;
PageController controller;
Timer timer;

@override
void initState() {
super.initState();
controller = PageController(
initialPage: realIndex,
//viewportFraction: 0.8//所占屏幕比例
);
timer = Timer.periodic(Duration(seconds: 2), (timer) { // 自动滚动
// print(realIndex);
controller.animateToPage(realIndex + 1,
duration: Duration(milliseconds: 500),
curve: Curves.linear);
});
}

@override
void dispose() {
super.dispose();
controller.dispose();
timer.cancel();
}

@override
Widget build(BuildContext context) {
return Container(
height: 200.0,
child: Stack(
alignment: Alignment.bottomCenter,//小点的位置
children: <Widget>[
PageView(
controller: controller,
onPageChanged: _onPageChanged,
children: _buildItems(),
),
_buildIndicator(), // 上面的小点
]),
);
}

List<Widget> _buildItems() { // 排列轮播数组
List<Widget> items = [];
if (widget.bannerStories.length > 0) {
// 头部添加一个尾部Item,模拟循环
items.add(
_buildItem(widget.bannerStories[widget.bannerStories.length - 1]));
// 正常添加Item
items.addAll(
widget.bannerStories.map((story) => _buildItem(story)).toList(
growable: false));
// 尾部
items.add(
_buildItem(widget.bannerStories[0]));
}
return items;
}
//每一个图片的点击事件
Widget _buildItem(StoryModel story) {
return GestureDetector(
onTap: () { // 按下
if (widget.onTap != null) {
widget.onTap(story);
}
},
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.network(story.image, fit: BoxFit.cover),
_buildItemTitle(story.title), // 内容文字,大意
],),);
}
//图片title
Widget _buildItemTitle(String title) {
return Container(
decoration: BoxDecoration( /// 背景的渐变色
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: const Alignment(0.0, -0.8),
colors: [const Color(0xa0000000), Colors.transparent],
),
),
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.symmetric(vertical: 22.0, horizontal: 16.0),
child: Text(
title, style: TextStyle(color: Colors.white, fontSize: 18.0),),),
);
}
//指示器显示
Widget _buildIndicator() {
List<Widget> indicators = [];
for (int i = 0; i < widget.bannerStories.length; i++) {
indicators.add(Container(
width: 6.0,
height: 6.0,
margin: EdgeInsets.symmetric(horizontal: 1.5, vertical: 10.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: i == virtualIndex ? Colors.white : Colors.grey)));
}
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: indicators);
}
//页面切换的时候
_onPageChanged(int index) {
realIndex = index;
int count = widget.bannerStories.length;
if (index == 0) {
virtualIndex = count - 1;
controller.jumpToPage(count);
} else if (index == count + 1) {
virtualIndex = 0;
controller.jumpToPage(1);
} else {
virtualIndex = index - 1;
}
setState(() {});
}
}

typedef void OnTapBannerItem(StoryModel story);

github源码地址: ​​https://github.com/1136346879/flutter_url_launcher_banner​


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  4koL3J55wyKx   2023年11月13日   34   0   0 icogitCentOS
  b1UHV4WKBb2S   2023年11月13日   36   0   0 ide抗锯齿
  b1UHV4WKBb2S   2023年11月13日   32   0   0 裁剪ideflutter
  zSWNgACtCQuP   2023年11月13日   29   0   0 ide
kXQGibE6SARU