flutter 列表展示
内容:
1、列表展示
2、轮播图
3、其他
本次的内容也是在上一节的基础上进行操作
我们就搞这个story模块。
目录:
story.dart story主页面
import 'package:flutter/material.dart'; import 'story_data.dart';
import 'story_item.dart';
void main() => runApp(Story()); class Story extends StatefulWidget {
@override
_Story createState() => new _Story();
} class _Story extends State<Story> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: ListView.builder(
itemCount: storyData.length,
// 构造列表项
itemBuilder: (BuildContext context, int index) {
// 传入MessageData返回列表项
return new StoryItem(storyData[index]);
},
),
);
}
}
story_item.dart 构造列表页面
import 'package:flutter/material.dart';
import 'story_data.dart';
import 'package:date_format/date_format.dart';
import '../common/touch_callback.dart';
import 'story_content.dart';
class StoryItem extends StatelessWidget {
final StoryData story;
StoryItem(this.story);
void main(){
print(this.story);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
decoration: BoxDecoration(
color: Colors.white,
// 底部边
border:
Border(bottom: BorderSide(width: 0.5, color: Color(0xFFd9d9d9))),
),
height: 64.0,
// 按下回调处理空实现
child: TouchCallBack(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// 展示头像
Container(
// 头像左右留一定外边距
margin: const EdgeInsets.only(left: 13.0, right: 13.0),
child: Image.asset(story.image, width: 48.0, height: 48.0,),
),
Expanded(
// 主标题和子标题采用垂直布局image/message_normal.png
child: Column(
// 垂直方向居中布局
mainAxisAlignment: MainAxisAlignment.center,
// 水平方向靠左对齐
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
story.title,
style: TextStyle(fontSize: 16.0, color:Color(0xFF353535)),
maxLines: ,
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
),
Text(
story.subTitle,
style: TextStyle(fontSize: 14.0, color:Color(0xFF9a9a9a)),
maxLines: ,
// 显示不完的文本用省略号来显示
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
onPressed: () {
// 跳转到新的页面
Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context){
return new StoryContent(story);
}));
},
),
);
}
}
里面涉及到两个公共库
touch_callback.dart 触摸回调
import 'package:flutter/material.dart'; // 触摸回调组件 class TouchCallBack extends StatefulWidget{ // 子组件
final Widget child; // 回调函数
final VoidCallback onPressed;
final bool isfeed; // 背景色
final Color background; // 传入参数列表
TouchCallBack({Key key,
@required this.child,
@required this.onPressed,
this.isfeed:true,
this.background:const Color(0xffd8d8d8),
}):super(key: key);
@override
TouchState createState() => TouchState(); } class TouchState extends State<TouchCallBack> {
Color color = Colors.transparent;
@override
Widget build(BuildContext context) {
// TODO: implement build
// 返回GestureDetector
return GestureDetector(
// 使用container容器包裹
child: Container(
color: color,
child: widget.child,
),
// onTap 回调
onTap: widget.onPressed,
onPanDown: (d) {
if(widget.isfeed == false) return;
setState(() {
color = widget.background;
});
},
onPanCancel: () {
setState(() {
color = Colors.transparent;
});
},
);
}
}
story_data.dart 模拟数据
// 聊天数据
class StoryData {
// id
var id; // 头像
String image; // 主标题
String title; // 副标题
String subTitle; // 描述
String description; // 图集
List imageList; StoryData( this.id, this.image, this.title, this.subTitle , this.description, this.imageList); } List<StoryData> storyData = [
new StoryData(
,
'images/story/01/cover.jpg',
'episode.1',
'プロローグ',
'因为黑沼爽子的外表看起来很阴沉,所以大家给她取了个“贞子”的外号,对想跟大家打成一片的爽子来说,个性开朗活泼又是大家中心人物的风早翔太就成了爽子心中憧憬的对象。在结业式前,爽子心中憧憬的对象风早约了爽子参加试胆大会。',
[
'images/story/01/01.jpg',
'images/story/01/02.jpg',
'images/story/01/03.jpg',
'images/story/01/04.jpg',
'images/story/01/05.jpg',
'images/story/01/06.jpg',
]
),
new StoryData(
,
'images/story/02/cover.jpg',
'episode.2',
'席替え',
'在大雨中淋的全身湿透的爽子到了学校,看到她这幅模样的同学们都感到无比的害怕,但是却因为这个机会,让爽子和吉田千鹤,矢野有了说话的机会,而爽子也很感谢风早很温柔的对待她。爽子也决定要趁这次换座位的机会下定决心要和坐在隔壁的同学好好相处,可是…。',
[
'images/story/02/01.jpg',
'images/story/02/02.jpg',
'images/story/02/03.jpg',
'images/story/02/04.jpg',
'images/story/02/05.jpg',
]
),
new StoryData(
,
'images/story/03/cover.jpg',
'episode.3',
'放课後',
'终於可以和自己憧憬的同学自然的说早安。正当爽子正在为这件事感动的时候,这学期代理班导的副班导荒井一市(通称:阿瓶)登场了,阿瓶正想要擅自决定谁来制作出席簿时,不想看到大家困扰的爽子就举起了手…。',
[]
),
new StoryData(
,
'images/story/04/cover.jpg',
'episode.4',
'噂',
'因为千鹤和矢野的关系,爽子终于再次尝到幸福的滋味。可是在学校中突然开始传出中伤千鹤和矢野的流言。虽然千鹤和矢野一开始听到传出谣言的人是爽子的时候是一笑置之不太相信,可是…。',
[]
),
new StoryData(
,
'images/story/05/cover.jpg',
'episode.5',
'决意',
'爽子以为千鹤和矢野的流言是因为自己的关系,而感到自责,所以为了不要再让千鹤和矢野受到伤害,决定回到独来独往的自己,而且也和风早保持距离以免风早也受到牵连。但是千鹤和矢野却被爽子突然冷漠的态度感到迷惘,一直拚命想找出答案。而风早则为了确定爽子的心意决定直接找上爽子…。',
[]
),
new StoryData(
,
'images/story/06/cover.jpg',
'episode.6',
'友達',
'爽子无意间在女生厕所内听到同年级的在谈论千鹤和矢野的谣言,爽子为了要澄清误会,却引起了大騒动,连爽子的同班同学们也都说谣言是爽子传的,但是却遭到风早强烈的否定。就在这个时候千鹤和矢野登场了…。',
[]
)
];
story_content.dart 故事详情
import 'package:flutter/material.dart';
import 'story_data.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:carousel_slider/carousel_slider.dart';
//import 'dart:math';
class StoryContent extends StatefulWidget {
final StoryData story;
StoryContent(this.story);
// StoryContent({Key key}) : super(key: key);
@override
_StoryContent createState() => new _StoryContent(story);
}
class _StoryContent extends State<StoryContent> {
// 获取参数story
final StoryData story;
_StoryContent(this.story);
String number = '';
String defaultIcon = '';
void main() {
print();
}
void _change() {
setState(() {
number = defaultIcon == ''? (int.parse(number) + ).toString(): (int.parse(number) - ).toString();
defaultIcon = defaultIcon == '' ? '': '';
});
print(story.imageList);
}
@override
Widget build(BuildContext context) {
ScreenUtil.instance = ScreenUtil(width: , height: )..init(context);
// TODO: implement build
return Scaffold(
appBar: new AppBar(
leading:
IconButton(icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context); // 返回
}
),
),
body: new Container(
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/bg/flower_one.jpg'),
fit: BoxFit.cover,
)),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
alignment: Alignment.center,
width: double.infinity,
margin: const EdgeInsets.only(top: 30.0, bottom: 10.0),
child: Text(
story.title + story.subTitle,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
),
new Container(
decoration: new BoxDecoration(
border: new Border.all(width: 1.0, color: Colors.pink),
color: Colors.grey,
borderRadius: new BorderRadius.all(new Radius.circular(4.0)),
),
width: ScreenUtil().setWidth(),
child: story.imageList.length != ? new CarouselSlider(
items: story.imageList.map((i) {
return new Builder(
builder: (BuildContext context) {
return new Container(
width: MediaQuery.of(context).size.width ,
// margin: new EdgeInsets.only(left: 0, right: 1.0),
decoration: new BoxDecoration(
color: Colors.amber
),
child: new Image.asset(
i,
fit: BoxFit.fill,
),
);
},
);
}).toList(),
height: 180.0,
autoPlay: false
) : Image.asset(story.image, fit:BoxFit.fill),
),
new Container(
margin: const EdgeInsets.only(top: 10.0, bottom: 10.0),
alignment: Alignment.center,
width: ScreenUtil().setWidth(),
child: Text(
story.description,
style: TextStyle(
letterSpacing: 2.0,
// wordSpacing: 15.0,
), ),
),
// 收藏
new Container(
margin: const EdgeInsets.only(top: 4.0, bottom: 10.0),
alignment: Alignment.bottomCenter,
width: ScreenUtil().setWidth(),
child: new Row(
children: <Widget>[
new IconButton(
icon: defaultIcon == '' ? const Icon(Icons.favorite_border, color: Colors.red) : const Icon(Icons.favorite, color: Colors.red),
onPressed: _change,
),
new Text(
number.toString(),
),
],
),
)
],
),
),
);
}
}
轮播插件
使用方法:
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart'; class Page2 extends StatelessWidget {
final imagesList = [
'xxxx.jpg',
'xxxx1.jpg',
'xxxx1.jpg',
]
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("carousel"),
),
body: new CarouselSlider(
items: imagesList.map((image) {
return new Builder(
builder: (BuildContext context) {
return new Container(
width: MediaQuery.of(context).size.width,
decoration: new BoxDecoration(
color: Colors.amber
),
child: new Image.assert(
image
fit: BoxFit.fill,
)
);
},
);
}).toList(),
height: 180.0,
autoPlay: false //自动播放
)
);
}
}
这里有个注意的地方,实时更新数据,渲染页面
setState(() {
number = defaultIcon == ''? (int.parse(number) + ).toString(): (int.parse(number) - ).toString();
defaultIcon = defaultIcon == '' ? '': '';
});
截图:
源码地址:https://github.com/ft1107949255/kiminitodoke
flutter 列表展示的更多相关文章
- Winform开发主界面菜单的动态树形列表展示
我在之前很多文章里面,介绍过Winform主界面的开发,基本上都是标准的界面,在顶部放置工具栏,中间区域则放置多文档的内容,但是在顶部菜单比较多的时候,就需要把菜单分为几级处理,如可以在顶部菜单放置一 ...
- JSP中列表展示,隔行变色以及S标签的使用
1.java代码 /** * 列表展示,隔行变色以及S标签的使用 * * @return */ public String list() { List<User> list = new A ...
- Vuex 教程案例:计数器以及列表展示
本案例github:https://github.com/axel10/Vuex_demo-Counter-and-list 本篇教程将以计数器及列表展示两个例子来讲解Vuex的简单用法. 从安装到启 ...
- Django--CRM-客户列表展示, 分页
一 . 客户列表展示 为了插入数据方便,我们可以用django里面的admin插入数据 创建超级用户 把语言改成中文 结果: 列表展示 展示不同字段的方式: # 有需要的可以写 def__str__( ...
- salesforce lightning零基础学习(七) 列表展示数据时两种自定义编辑页面
上一篇Lightning内容描述的是LDS,通过LDS可以很方便的实例化一个对象的数据信息.当我们通过列表展示数据需要编辑时,我们常使用两种方式去处理编辑页面:Pop Up Window弹出修改详情以 ...
- [android] 手机卫士黑名单功能(列表展示)
先把要拦截的电话号码保存到数据库中,拦截模式用个字段区分,1 电话拦截,2 短信拦截,3全部拦截 新建Activity类CallSmsSafeActivity.java 新建布局文件activity_ ...
- (转)淘淘商城系列——MyBatis分页插件(PageHelper)的使用以及商品列表展示
http://blog.csdn.net/yerenyuan_pku/article/details/72774381 上文我们实现了展示后台页面的功能,而本文我们实现的主要功能是展示商品列表,大家要 ...
- 使用css3的Flex布局实现列表展示
实现效果图如下: 通过css3样式实现(部分代码): .box { display: flex; flex-wrap:wrap; justify-content:space-between; alig ...
- 循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理
在我们一般开发的系统界面里面,列表页面是一个非常重要的综合展示界面,包括有条件查询.列表展示和分页处理,以及对每项列表内容可能进行的转义处理,本篇随笔介绍基于Vue +Element基础上实现表格列表 ...
随机推荐
- python学习之初识字符串
刚接触一门语言时,字符串是很容易遇到的, 例如要从读入或者写出, 字符串与数字间的转换等. 由于字符串, 列表和元组等类型具有一定的共性(由对象组成的序列,如字符串是字符序列), 在Python中统称 ...
- 复杂透视表的SQL生成方法
一般而言,利用表单查看数据时,会从不同的维度来涉及透视表.比如,从产品和时间维度分析销售数据. 当需要从时间维度去分析时,同时希望能有同比,环比数据,那么将时间维度设计成列将极大方便SQL的编写. 如 ...
- python websocket Django 实时消息推送
概述: WebSocket 是什么? WebSocket 是 HTML5 提供的一种浏览器与服务器间进行全双工通讯的协议.依靠这种协议可以实现客户端和服务器端 ,一次握手,双向实时通信. WebSoc ...
- 加载xib文件,如果想在初始化的时候就添加点东西就重载-(id)initWithCoder:(NSCoder *)aDecoder
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { self.cl ...
- 18.python关于mysql的api
一.pymysql模块1.pymysql是Python中操作MySQL的模块2.执行sql语句(1)连接数据库: import pymysql #连接mysql数据库创建conn对象(host连接的机 ...
- openpyxl工具总结
1.openpyxl使用 涉及到单元格合并.赋值 ''' .格式转换 raw_data create_data boolean Bool uint8 UInt8 int8 Int8 uint16 UI ...
- buildroot管理uboot+kernel+rootfs
鉴于自己制作根文件系统太麻烦了,所以想用buildroot管理uboot,kernel,另外还可以自动生产rootfs,于是花了两天研究了下buildroot的框架和使用,在自己的2440开发板上也跑 ...
- 为什么要学习socket
为什么要学习socket socket历史悠久.它们的使用始于 1971年的ARPANET,后来成为1983年发布的Berkeley Software Distribution(BSD)操作系统中的A ...
- XPATH 要想获取的东西里不分段,不变成列表就用STRING(),不用TEXT()
简单说一说: requests配合xpath来抓网站数据的时候,不像selenium+xpath. selenium有 find_element find_elements,区别是带S ,查找第一 ...
- 链路聚合trunk实现
用户需求 1,在原有网络基础上实现用户接入Internet 2,监控摄像头不改变原有功能 配置思路 1,首先确定接入交换机是否为管理型交换机 2, 确认接入交换机管理IP 3,划分Vlan 创建tr ...