在挪动开发中,下拉弹框是一种很常见的抉择交互方式,成果如下图所示。

对于这种弹框,咱们能够应用Dialog来实现,上面是自定义弹框的次要代码。

Color _bgColor = Colors.white;double cellHeight = 34;double cellWidth=120;typedef ClickCallBack = void Function(int selectIndex, String selectText);class PopMenus {  static void showPop(      {@required BuildContext context,      @required List<String> listData,      @required String selText,      ClickCallBack clickCallback}) {    Widget _buildMenuLineCell(dataArr) {      return ListView.separated(        itemCount: dataArr.length,        physics: const NeverScrollableScrollPhysics(),        itemBuilder: (BuildContext context, int index) {          return GestureDetector(              onTap: () {                Navigator.pop(context);                if (clickCallback != null) {                  clickCallback(index, listData[index]);                }              },              child: Container(                height: cellHeight,                child: Column(                  crossAxisAlignment: CrossAxisAlignment.center,                  mainAxisAlignment: MainAxisAlignment.center,                  children: <Widget>[                    selText==dataArr[index]?                    Text(dataArr[index], style: TextStyle(fontSize: 16,color:                    Colors.blue)):Text(dataArr[index], style: TextStyle(fontSize: 16))                  ],                ),              ));        },        separatorBuilder: (context, index) {          return Divider(            height: 0.1,            color: Color(0xFFE6E6E6),          );        },      );    }    _buildMenusView(dataArr) {      var cellH = dataArr.length * cellHeight;      var navH = ScreenUtils.navigationBarHeight;      navH = navH - ScreenUtils.topSafeHeight;      var leftP=(ScreenUtils.screenWidth-cellWidth)/2;      return Positioned(        left: leftP,        top: navH-10,        child: Column(          crossAxisAlignment: CrossAxisAlignment.end,          children: <Widget>[            Container(              padding: EdgeInsets.only(right: 10),              child: TriangleUpWidget(height: 10,width: 14),            ),            ClipRRect(                borderRadius: BorderRadius.circular(2),                child: Container(                    color: _bgColor,                    width: cellWidth,                    height: cellH,                    child: _buildMenuLineCell(dataArr)))          ],        ),      );    }    showDialog(        context: context,        barrierDismissible: false,        builder: (context) {          return BasePopMenus(child: _buildMenusView(listData));        });  }}class BasePopMenus extends Dialog {  BasePopMenus({    Key key,    this.child,  }) : super(key: key);  final Widget child;  @override  Widget build(BuildContext context) {    return Material(      type: MaterialType.transparency,      child: Stack(        fit: StackFit.expand,        children: <Widget>[          GestureDetector(onTap: () => Navigator.pop(context)),          child        ],      ),    );  }}

如果须要扭转弹框的地位,能够批改_buildMenusView()办法中的Positioned组件的边距代码。下面的代码中用到了一个自定义三角形,代码如下。

class TriangleUpPainter extends CustomPainter {  Color color; //填充色彩  Paint _paint; //画笔  Path _path; //绘制门路  double angle; //角度  TriangleUpPainter() {    _paint = Paint()      ..strokeWidth = 1.0 //线宽      ..color = Colors.white      ..isAntiAlias = true;    _path = Path();  }  @override  void paint(Canvas canvas, Size size) {    final baseX = size.width;    final baseY = size.height;    //终点    _path.moveTo(baseX*0.5, 0);    _path.lineTo(baseX, baseY);    _path.lineTo(0, baseY);    canvas.drawPath(_path, _paint);  }  @override  bool shouldRepaint(CustomPainter oldDelegate) {    return false;  }}class TriangleUpWidget extends StatefulWidget {  double height;  double width;  TriangleUpWidget({Key key, this.height = 14, this.width = 16}) : super(key:  key);  @override  CoreTriangleState createState() => CoreTriangleState();}class CoreTriangleState extends State<TriangleUpWidget> {  @override  Widget build(BuildContext context) {    return Container(        height: widget.height,        width: widget.width,        child: CustomPaint(          painter: TriangleUpPainter(),        ));  }}

最初,在须要弹框的中央,调用咱们自定义的弹框组件即可,如下所示。

PopMenus.showPop(context: context, listData: segmentLists,      selText: selectedTab, clickCallback: (int index, String value){                   });