[TOC]
Another exception was thrown: A dismissed Dismissible widget is still part of the tree.
具体代码为
ListView.builder(
itemBuilder: (context, index) {
var item = _list[index];
debugPrint('the key is ${index.toString()}');
return Dismissible(
key: Key(item.id.toString()),
confirmDismiss: (DismissDirection direction) async {
final bool res = await showDialog(
context: context,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text(
"注意",
style: TextStyle(
fontSize: 16, color: ColorConf.color000000),
),
content: const Text("您是否要取消收藏这个文章呢?"),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop(true);
_deleteItem(item.id, item.originId, index);
},
child: Text(
"是的",
style: TextStyle(
fontSize: 14,
color: ColorConf.colorGreen),
)),
FlatButton(
onPressed: () =>
Navigator.of(context).pop(false),
child: Text(
"CANCEL",
style: TextStyle(
fontSize: 14,
color: ColorConf.color48586D),
),
)
],
);
});
return res;
},
background: Container(
padding: const EdgeInsets.only(right: 30),
alignment: Alignment.centerRight,
color: Colors.red,
child: Text(
'滑动取消收藏',
style:
TextStyle(fontSize: 16, color: ColorConf.colorFFFFFF),
),
),
child: Container(
child: Column(
children: <Widget>[
ProjectWidget.renderListViewCollectionItem(
_list[index], () {}),
Divider(),
],
)),
);
},
itemCount: _list.length)
具体表现为:删除了某个item后再去下拉更新数据,会报错,可能是因为key的问题,所以修改为:
key: Key(UniqueKey().toString()),
表现良好
showModalBottomSheet 输入框被输入法遮挡
效果图:
微信图片_20190923141123.png 微信图片_20190923141130.png
主要是两个问题:
/// 选择弹窗
_showChooseDialog(BuildContext context) {
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
useRootNavigator: true,
context: context,
builder: (_) => ChooseDialog());
}
showModalBottomSheet 高度
默认属性为高度为页面高度的1/2,这里设置为
isScrollControlled: true, 即dialog高度为页面高度的100%;
dialog可滚动且resizeToAvoidBottomPadding: true,
子布局添加
@override
Widget build(BuildContext context) {
debugPrint(
'MediaQuery.of(context).viewInsets.bottom is ${MediaQuery.of(context).viewInsets.bottom}');
return Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomPadding: true,
body: Container(
alignment: Alignment.bottomCenter,
child: SingleChildScrollView(
child: _initBody(context),
),
));
}
页面滚动是因为原页面太高,滚动后会出现越界,这边添加滚动。
而为了让输入法顶出输入框,这边顶层布局修改为Scaffold,且添加:
resizeToAvoidBottomPadding: true,
/// This flag is deprecated, please use [resizeToAvoidBottomInset]
/// instead.
///
/// Originally the name referred [MediaQueryData.padding]. Now it refers
/// [MediaQueryData.viewInsets], so using [resizeToAvoidBottomInset]
/// should be clearer to readers.
@Deprecated('Use resizeToAvoidBottomInset to specify if the body should resize when the keyboard appears')
final bool resizeToAvoidBottomPadding;
折叠布局
import 'package:flutter/material.dart';
import 'package:flutter_shop_index/utils/ColorConf.dart';
import 'package:flutter_shop_index/utils/StyleConf.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'homeChild/HomeChildPage.dart';
class HomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HomePage();
}
}
class _HomePage extends State<HomePage> with TickerProviderStateMixin {
List<String> _title = [];
List<String> _classImgList = [];
TabController _tabController;
@override
void initState() {
_title.clear();
_title.add("热门推荐");
_title.add("积分可换");
_title.add("限时兑购");
_title.add("新品上线");
_title.add("品牌专区");
_classImgList.clear();
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/20983/16/10753/6124/5c8a16aaE5d6b15d7/01e0e818a7505267.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/39401/17/2391/5859/5cc06fcfE2ad40668/28cda0a571b4a576.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/17169/3/4127/4611/5c2f35cfEd87b0dd5/65c0cdc1362635fc.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t17725/156/1767366877/17404/f45d418b/5ad87bf0N66c5db7c.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t16990/157/2001547525/17770/a7b93378/5ae01befN2494769f.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t16990/157/2001547525/17770/a7b93378/5ae01befN2494769f.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t18454/342/2607665324/6406/273daced/5b03b74eN3541598d.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t22228/270/207441984/11564/88140ab7/5b03fae3N67f78fe3.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/7068/29/8987/5605/5c120da2Ecae1cc3a/016033c7ef3e0c6c.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t16828/63/2653634926/5662/d18f6fa1/5b03b779N5c0b196f.png');
_classImgList.add(
'https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/22262/9/1470/4527/5c120cd0E5d3c6c66/4792ec307a853e9f.png');
_tabController =
new TabController(length: _title.length, vsync: this, initialIndex: 0);
super.initState();
}
@override
Widget build(BuildContext context) {
double statusBarHeight = MediaQuery.of(context).padding.top;
double _bannerHeight = 190 + 10.0;
double _classHeight = 190;
double _pointHeight = 30;
double _appBarHeight = _bannerHeight +
_pointHeight +
_classHeight -
kToolbarHeight -
statusBarHeight;
_tabController.index=4;
return Scaffold(
appBar: AppBar(
backgroundColor: ColorConf.colorFFFFFF,
centerTitle: true,
title: Text(
"积分商城",
style: StyleConf.style2048586DBold,
),
actions: <Widget>[
IconButton(
icon: ImageIcon(
AssetImage(
'images/iconSearch.png',
),
color: ColorConf.color48586D,
),
onPressed: () {},
),
IconButton(
icon: ImageIcon(
AssetImage(
'images/iconMore.png',
),
color: ColorConf.color48586D,
),
onPressed: () {},
),
],
),
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: SliverAppBar(
backgroundColor: Color(0xfff1f1f1),
forceElevated: innerBoxIsScrolled,
bottom: PreferredSize(
child: Container(),
preferredSize: Size.fromHeight(_appBarHeight)),
flexibleSpace: Column(
children: <Widget>[
_initBanner(_bannerHeight),
_initPointBar(_pointHeight),
_initProClass(_classHeight),
],
),
),
),
SliverPersistentHeader(
delegate: _SliverAppBarDelegate(_initTabBar()),
pinned: true,
),
];
},
body: _initTabBarView()),
);
}
/// 初始化tab Menu
/// 这个Widget 可用于bottom以及center中部菜单
/// 可用于 [appBar]的[bottom]
/// 可用于[body]的item
Widget _initTabBarView() {
return TabBarView(
children: _title.map((e) => HomeChildPage()).toList(),
controller: _tabController,
);
}
/// 初始化tab Menu
/// 这个Widget 可用于bottom以及center中部菜单
/// 可用于 [appBar]的[bottom]
/// 可用于[body]的item
Widget _initTabBar() {
return Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
color: ColorConf.colorFFFFFF,
),
_initTabItem(),
],
);
}
/// 初始化每一个tabBar的每一个item ,主要用于[_initTabBar]
Widget _initTabItem() {
return TabBar(
isScrollable: true,
labelStyle: StyleConf.style1448586D,
unselectedLabelStyle: StyleConf.style14A1A9B4,
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(
image: DecorationImage(
alignment: Alignment.bottomCenter,
image: AssetImage(
'images/IconLandscape.png',
))),
labelColor: ColorConf.color48586D,
unselectedLabelColor: ColorConf.color929292,
tabs: _title
.map((e) => Tab(
child: Container(
child: Text(e),
padding: const EdgeInsets.only(
bottom: 0,
),
),
))
.toList(),
controller: _tabController,
);
}
/// 初始化banner
Widget _initBanner(height) {
return Expanded(
child: Container(
height: height,
child: Swiper(
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
repeat: ImageRepeat.noRepeat,
image: NetworkImage(
'https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/51092/36/11835/138581/5d89eec9E161806d2/83a2e56cd03a6817.jpg!cr_1125x445_0_171!q70.jpg.dpg',
),
)),
);
},
itemCount: 3,
pagination: new SwiperPagination(builder: SwiperPagination.dots),
),
));
}
/// 商品分类
Widget _initProClass(height) {
return Container(
height: height,
color: ColorConf.colorFFFFFF,
padding: const EdgeInsets.only(top: 10, left: 14, right: 14, bottom: 10),
child: GridView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
mainAxisSpacing: 10,
childAspectRatio: 0.75,
crossAxisSpacing: 10),
itemBuilder: (context, index) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
height: 50,
margin: const EdgeInsets.only(bottom: 4),
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
),
child: Image.network(
_classImgList[index],
scale: 0.5,
),
),
Expanded(
child: Text(
'调养优品',
style: StyleConf.style1248586D,
))
],
);
}),
);
}
/// 积分栏
Widget _initPointBar(height) {
return Container(
height: height,
padding: const EdgeInsets.only(left: 14, right: 14, top: 4, bottom: 4),
color: ColorConf.color18C8A1,
child: Row(
children: <Widget>[
Text(
'可用积分:12212120',
style: StyleConf.style14FFFFFF,
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text('兑换记录', style: StyleConf.style14FFFFFF),
Icon(
Icons.chevron_right,
color: ColorConf.colorFFFFFF,
)
],
))
],
),
);
}
}
/// SliverAppBar代理
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
final Stack _tabBar;
_SliverAppBarDelegate(this._tabBar);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return _tabBar;
}
@override
double get maxExtent => 41;
@override
double get minExtent => 41;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
return false;
}
}
网友评论