一.listview 简介
1.listview源码查看,listview是最常见的组件之一,对于列表的展示一般首选listview,下面看下listview中的构造函数eg :
/// It is usually more efficient to create children on demand using
/// [ListView.builder] because it will create the widget children lazily as necessary.
///
/// The `addAutomaticKeepAlives` argument corresponds to the
/// [SliverChildListDelegate.addAutomaticKeepAlives] property. The
/// `addRepaintBoundaries` argument corresponds to the
/// [SliverChildListDelegate.addRepaintBoundaries] property. The
/// `addSemanticIndexes` argument corresponds to the
/// [SliverChildListDelegate.addSemanticIndexes] property. None
/// may be null.
ListView({
Key? key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController? controller,
bool? primary,
ScrollPhysics? physics,
bool shrinkWrap = false,
EdgeInsetsGeometry? padding,
//ListView各个构造函数的共同参数
this.itemExtent,
this.prototypeItem,//列表项原型
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double? cacheExtent,// 预渲染区域长度
List<Widget> children = const <Widget>[],//子widget列表
int? semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String? restorationId,
Clip clipBehavior = Clip.hardEdge,
})
itemExtent //该参数如果不为null,则会强制children的“长度”为itemExtent的值
prototypeItem //指定列表项的长度,所以和指定 itemExtent 一样,指定 prototypeItem 会有更好的性能,但itemExtent 和prototypeItem不能同时指定
shrinkWrap //设置ListView的长度,默认值为false,如果ListView要设置为一个无边界的容器时,shrinkWrap必须为true
2.ListTile源码查看及介绍,ListTile相当于android listview中的item,用于填充listview,ListTile中提供了一些常用的属性,包括icon,text,点击事件etc,eg:
const ListTile({
Key? key,
this.leading, //item左边的图标
this.title, //标题
this.subtitle, //子标题
this.trailing, //item右边的图标
this.isThreeLine = false, //是否显示三行
this.dense, //是否使用缩小布局
this.visualDensity, //紧凑程度,VisualDensity
this.shape, //形状,这里边缘颜色无效,再点击时阴影可以看出来效果
this.contentPadding, //content内边距
this.enabled = true, //是否可用,仅改变颜色,默认为 true
this.onTap, //点击事件
this.onLongPress, //长按事件
this.mouseCursor, //是否可用,仅改变颜色,默认为 true
this.selected = false, //是否选中状态,是否可用,仅改变颜色,默认为 true
this.focusColor, //聚焦颜色
this.hoverColor, //悬停颜色
this.focusNode, //焦点控制
this.autofocus = false, //自动聚焦,默认为 false
this.tileColor,
this.selectedTileColor,
this.enableFeedback,
this.horizontalTitleGap,
this.minVerticalPadding,
this.minLeadingWidth,
})
二.Dialog介绍
1.AlertDialog属性介绍
1).源码查看,eg:
const AlertDialog({
Key? key,
this.title, //标题
this.titlePadding, //标题外间距
this.titleTextStyle, //标题样式 TextStyle
this.content, //内容显示
this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0), //内容外间距
this.contentTextStyle, //内容文本样式 TextStyle
this.actions, //事件子控件组
this.actionsPadding = EdgeInsets.zero, //事件子控件间距,默认为 EdgeInsets.zero,
this.actionsAlignment,
this.actionsOverflowDirection, //事件过多时,竖向展示顺序,只有正向和反向,默认为 VerticalDirection.down
this.actionsOverflowButtonSpacing, //事件过多时,竖向展示时,子控件间距
this.buttonPadding, //actions 中每个按钮边缘填充距离,默认为左右各 8.0
this.backgroundColor, //背景色
this.elevation, //阴影高度
this.semanticLabel, //语义标签
this.insetPadding = _defaultInsetPadding, //对话框距离屏幕边缘间距
this.clipBehavior = Clip.none, //超出部分剪切方式,Clip.none
this.shape, //形状 ShapeBorder
this.scrollable = false, //是否可以滚动,默认为 false
})
2).AlertDialog代码片段
Future alertDialog() async {
var alertDialogs = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("提示"),
content: Text("确定要修改吗"),
actions: <Widget>[
FlatButton(
child: Text("取消"),
onPressed: () => Navigator.pop(context, "cancel")),
FlatButton(
child: Text("确定"),
onPressed: () => Navigator.pop(context, "yes")),
],
);
});
return alertDialogs;
}
2.SimpleDialog属性介绍
1).源码查看,eg:
const SimpleDialog({
Key? key,
this.title, //标题
this.titlePadding = const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0), //标题外间距
this.titleTextStyle, //标题样式 TextStyle
this.children, //子控件,可以随意自定义
this.contentPadding = const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0), //内容外间距
this.backgroundColor, //背景色
this.elevation, //阴影高度
this.semanticLabel, //语义标签
this.insetPadding = _defaultInsetPadding,
this.clipBehavior = Clip.none,
this.shape, //形状 ShapeBorder
})
2)..SimpleDialog代码片段
Future alertSimpleDialog() async {
var alertDialogs = await showDialog(
context: context,
builder: (context) {
return SimpleDialog(
title: Text("提示"),
children: <Widget>[
FlatButton(
child: Text("Option1"),
onPressed: () => Navigator.pop(context, "Option1"),
),
FlatButton(
child: Text("Option2"),
onPressed: () => Navigator.pop(context, "Option2"),
),
FlatButton(
child: Text("Option3"),
onPressed: () => Navigator.pop(context, "Option3"),
),
],
);
});
return alertDialogs;
}
3.toast介绍,可参考toast弹窗实现
4.自定义dialog
1).dialog 属性介绍
const Dialog({
Key? key,
this.backgroundColor, //背景色
this.elevation, //阴影高度
this.insetAnimationDuration = const Duration(milliseconds: 100), //动画时间
this.insetAnimationCurve = Curves.decelerate, //动画效果,渐进渐出等等
this.insetPadding = _defaultInsetPadding, //对话框距离屏幕边缘间距
this.clipBehavior = Clip.none, //超出部分剪切方式
this.shape, 形状 ShapeBorder
this.child, //自定义弹框
})
2).dialog自定义,需要继承Dialog,eg:
class ListviewDialog extends Dialog {
List<String>data=[
"游戏",
"视频",
"财经",
"体育",];
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Material(
//透明层
type: MaterialType.transparency, //透明类型
child: new Center(
//控件居中
child: new SizedBox(
width: 200.0,
height: 180.0,
child: new Container(
color: Colors.white,
child: ListView.builder(
itemCount:data.length==0?0:data.length,
itemBuilder: (BuildContext context, int position){
return itemWidget(context,position);
}),
),
),
),
);;
}
Widget itemWidget(BuildContext context,int index){
return GestureDetector(
child: Container(
height: 45,
width: double.infinity,
child: Center(
child: Text(
data[index],
style: TextStyle(
color: Colors.black
),
),
)
),
onTap: (){
Navigator.pop(context,data[index]);
},
);
}
}
三.demo 展示,通过英文随机单词显示listview,且点击listview弹出点击单词的toast,长按弹出自定义的dialog
1.需要在pubspec.yaml中配置依赖库,eg:
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
english_words: ^4.0.0
2.实现RandomWordsTest.dart文件
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
import 'package:fluttertoast/fluttertoast.dart';
class RandomWords extends StatefulWidget{
@override
_RandomWordsState createState()=>_RandomWordsState();
}
class _RandomWordsState extends State<RandomWords>{
final _suggestions=<WordPair>[];
final _biggerFont=const TextStyle(fontSize: 16.0);
@override
Widget build(BuildContext context) {
/*final wordpair=WordPair.random();
return Text(wordpair.asPascalCase);*/
return Scaffold(
appBar: AppBar(
title: const Text('Random words list'),
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions(){
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context,i){
if(i.isOdd) return const Divider();
final index=i~/2;
if(index>=_suggestions.length){
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
Widget _buildRow(WordPair pair){
return ListTile(
leading: Icon(Icons.tab_rounded),// 右侧组件图标
trailing: Icon(Icons.table_view_sharp), // 右侧组件图标
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
onLongPress: (){//长按事件
setState(() {
showCustomDialog(context).then((value) {//显示dialog
print("回调值是--- > "+pair.asPascalCase);
});
});
},
onTap: (){//点击事件回调
Fluttertoast.showToast(//消息提醒
msg: pair.asPascalCase,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.white,
textColor: Colors.black,
fontSize: 18.0
);
},
);
}
Future showCustomDialog(BuildContext context )async {
var result=await showDialog(
context: context,
builder: (BuildContext context) {
return ListviewDialog();
});
return result;
}
}
class ListviewDialog extends Dialog {
List<String>data=[
"游戏",
"视频",
"财经",
"体育",];
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Material(
//透明层
type: MaterialType.transparency, //透明类型
child: new Center(
//控件居中
child: new SizedBox(
width: 200.0,
height: 180.0,
child: new Container(
color: Colors.white,
child: ListView.builder(
itemCount:data.length==0?0:data.length,
itemBuilder: (BuildContext context, int position){
return itemWidget(context,position);
}),
),
),
),
);;
}
Widget itemWidget(BuildContext context,int index){
return GestureDetector(
child: Container(
height: 45,
width: double.infinity,
child: Center(
child: Text(
data[index],
style: TextStyle(
color: Colors.black
),
),
)
),
onTap: (){
Navigator.pop(context,data[index]);
},
);
}
}