Info Popup Window | Create Popup window in Flutter Listview

Last updated Mar 01, 2021

Some times we might be show the content with popup  on the current screen due to the device width and height to make proper UI design.  Popup is useful when we want to show some additional information or else submit feedback, etc. In this post we are going to create a Popup window in the flutter listview examples. 

In this Popup window flutter example we are showing the info window on the listview items.

 

Let's get started

Step 1: Create android application

Step 2: Create Popup window file which we are going to show as popup

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
const Duration _kWindowDuration = const Duration(milliseconds: 0);
const double _kWindowCloseIntervalEnd = 2.0 / 3.0;
const double _kWindowMaxWidth = 240.0;
const double _kWindowMinWidth = 48.0;
//double _kWindowMinWidth = Get.width/2;
const double _kWindowVerticalPadding = 0.0;
const double _kWindowScreenPadding = 0.0;
Future<T> showPopupWindow<T>({
  @required BuildContext context,
  RelativeRect position,
  @required Widget child,
  double elevation: 8.0,
  String semanticLabel,
  bool fullWidth,
  bool isShowBg = false,
}) {
  assert(context != null);
  String label = semanticLabel;
  switch (defaultTargetPlatform) {
    case TargetPlatform.iOS:
      label = semanticLabel;
      break;
    case TargetPlatform.android:
      break;
    case TargetPlatform.fuchsia:
      label =
          semanticLabel ?? MaterialLocalizations.of(context)?.popupMenuLabel;
      break;
    case TargetPlatform.linux:
      break;
    case TargetPlatform.macOS:
      break;
    case TargetPlatform.windows:
      break;
  }
  return Navigator.push(
      context,
      new _PopupWindowRoute(
          context: context,
          position: position,
          child: child,
          elevation: elevation,
          semanticLabel: label,
          theme: Theme.of(context, shadowThemeOnly: true),
          barrierLabel:
          MaterialLocalizations.of(context).modalBarrierDismissLabel,
          fullWidth: fullWidth,
          isShowBg: isShowBg));
}
class _PopupWindowRoute<T> extends PopupRoute<T> {
  _PopupWindowRoute({
    @required BuildContext context,
    RouteSettings settings,
    this.child,
    this.position,
    this.elevation: 8.0,
    this.theme,
    this.barrierLabel,
    this.semanticLabel,
    this.fullWidth,
    this.isShowBg,
  }) : super(settings: settings) {
    assert(child != null);
  }
  final Widget child;
  final RelativeRect position;
  double elevation;
  final ThemeData theme;
  final String semanticLabel;
  final bool fullWidth;
  final bool isShowBg;
  @override
  Color get barrierColor => null;
  @override
  bool get barrierDismissible => true;
  @override
  final String barrierLabel;
  @override
  Duration get transitionDuration => _kWindowDuration;
  @override
  Animation<double> createAnimation() {
    return new CurvedAnimation(
        parent: super.createAnimation(),
        curve: Curves.linear,
        reverseCurve: const Interval(0.0, _kWindowCloseIntervalEnd));
  }
  @override
  Widget buildPage(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation) {
    Widget win = new _PopupWindow<T>(
      route: this,
      semanticLabel: semanticLabel,
      fullWidth: fullWidth,
    );
    if (theme != null) {
      win = new Theme(data: theme, child: win);
    }
    return new MediaQuery.removePadding(
      context: context,
      removeTop: true,
      removeBottom: true,
      removeLeft: true,
      removeRight: true,
      child: new Builder(
        builder: (BuildContext context) {
          return Material(
            type: MaterialType.transparency,
            child: GestureDetector(
              onTap: () {
                Get.back();
                // NavigatorUtils.goBack(context);
              },
              child: Container(
                width: double.infinity,
                height: double.infinity,
                color: isShowBg ? Color(0x99000000) : null,
                child: new CustomSingleChildLayout(
                  delegate: new _PopupWindowLayoutDelegate(
                      position, null, Directionality.of(context)),
                  child: win,
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}
class _PopupWindow<T> extends StatelessWidget {
  const _PopupWindow({
    Key key,
    this.route,
    this.semanticLabel,
    this.fullWidth: false,
  }) : super(key: key);
  final _PopupWindowRoute<T> route;
  final String semanticLabel;
  final bool fullWidth;
  @override
  Widget build(BuildContext context) {
    final double length = 10.0;
    final double unit = 1.0 /
        (length + 1.5); // 1.0 for the width and 0.5 for the last item's fade.
    final CurveTween opacity =
    new CurveTween(curve: const Interval(0.0, 1.0 / 3.0));
    final CurveTween width = new CurveTween(curve: new Interval(0.0, unit));
    final CurveTween height =
    new CurveTween(curve: new Interval(0.0, unit * length));
    final Widget child = new ConstrainedBox(
        constraints: new BoxConstraints(
          minWidth: fullWidth ? double.infinity : _kWindowMinWidth,
          maxWidth: fullWidth ? double.infinity : Get.width / 1.15,
        ),
        child: new SingleChildScrollView(
          //padding: EdgeInsets.all(20),
          padding:
          const EdgeInsets.symmetric(vertical: _kWindowVerticalPadding),
          child: route.child,
        ));
    return new AnimatedBuilder(
      animation: route.animation,
      builder: (BuildContext context, Widget child) {
        return new Opacity(
          opacity: opacity.evaluate(route.animation),
          child: new Material(
            type: route.elevation == 0
                ? MaterialType.transparency
                : MaterialType.card,
            elevation: route.elevation,
            child: new Align(
              alignment: AlignmentDirectional.topEnd,
              widthFactor: width.evaluate(route.animation),
              heightFactor: height.evaluate(route.animation),
              child: new Semantics(
                scopesRoute: true,
                namesRoute: true,
                explicitChildNodes: true,
                label: semanticLabel,
                child: child,
              ),
            ),
          ),
        );
      },
      child: child,
    );
  }
}
class _PopupWindowLayoutDelegate extends SingleChildLayoutDelegate {
  _PopupWindowLayoutDelegate(
      this.position, this.selectedItemOffset, this.textDirection);
  final RelativeRect position;
  final double selectedItemOffset;
  final TextDirection textDirection;
  @override
  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
    return new BoxConstraints.loose(constraints.biggest -
        const Offset(_kWindowScreenPadding * 2.0, _kWindowScreenPadding * 2.0));
  }
  @override
  Offset getPositionForChild(Size size, Size childSize) {
    double y;
    if (selectedItemOffset == null) {
      y = position.top;
    } else {
      y = position.top +
          (size.height - position.top - position.bottom) / 2.0 -
          selectedItemOffset;
    }
    // Find the ideal horizontal position.
    double x;
    x = (size.width - childSize.width) / 2;

    if (x < _kWindowScreenPadding) {
      x = _kWindowScreenPadding;
    } else if (x + childSize.width > size.width - _kWindowScreenPadding) {
      x = size.width - childSize.width - _kWindowScreenPadding;
    }
    if (y < _kWindowScreenPadding)
      y = _kWindowScreenPadding;
    else if (y + childSize.height > size.height - _kWindowScreenPadding)
      y = size.height - childSize.height - _kWindowScreenPadding;
    return new Offset(x, y);
  }
  @override
  bool shouldRelayout(_PopupWindowLayoutDelegate oldDelegate) {
    return position != oldDelegate.position;
  }
}

 

Step 3: Create dart file where we are going to show list of items and display popup window on tap on any widget

import 'package:flutter/material.dart';

import 'popupwindow.dart';

class MyPopupWidget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    var _infoKey = List<GlobalKey>();

   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(title: Text("Popup Window"),backgroundColor: Colors.pink,),
       backgroundColor: Colors.blueGrey,
       body: Container(
         margin: EdgeInsets.all(8),
         child: ListView.builder(
             cacheExtent: 10000.0,
             itemCount: 2,
             /*_homeController
                          .configResponse.value.configLayoutList.length,*/
             itemBuilder: (context, index) {
               _infoKey.add(GlobalKey(debugLabel: index.toString()));
               return Card(
                   elevation: 1.5,
                   child: Container(
                       margin: EdgeInsets.all(10),
                       child: Column(children: [
                         Row(
                             mainAxisAlignment:
                             MainAxisAlignment.spaceBetween,
                             children: [
                               Column(
                                   crossAxisAlignment:
                                   CrossAxisAlignment.start,
                                   children: [
                                     Text("Bill ID: 2021",
                                         style: TextStyle(
                                           color: Colors.black,
                                           fontSize: 12,

                                         )),
                                     Text("Home Delivery",
                                         style: TextStyle(
                                           color: Colors.deepOrange,
                                           fontSize: 12,
                                         )),
                                   ]),
                               Column(
                                   crossAxisAlignment:
                                   CrossAxisAlignment.end,
                                   children: [
                                     Text('12-11-2019 - 8:30 PM',
                                         style: TextStyle(
                                           color: Colors.blueGrey,
                                           fontSize: 12,
                                         )),
                                     Text('22 min ago',
                                         style: TextStyle(
                                           color: Colors.grey,
                                           fontSize: 10,
                                         ))
                                   ])
                             ]),
                         SizedBox(height: 5),
                         Row(children: [
                           Flexible(
                               flex: 2500,
                               child: Row(children: [
                                 Icon(Icons.check_circle_outline,
                                     color: Colors.red, size: 14),
                                 SizedBox(width: 5),
                                 Text('Frawns',
                                     style: TextStyle(
                                       color: Colors.black,
                                       fontSize: 14,

                                     ))
                               ])),
                           Flexible(
                               flex: 700,
                               child: Row(children: [
                                 Text('X',
                                     style: TextStyle(
                                       color: Colors.grey,
                                       fontSize: 14,

                                     )),
                                 Text('1',
                                     style: TextStyle(
                                       color: Colors.grey,
                                       fontSize: 12,

                                     ))
                               ])),
                           Flexible(
                               flex: 0,
                               child: Text('\u20B9 2000',
                                   style: TextStyle(
                                     color: Colors.grey,
                                     fontSize: 12,

                                   ))),
                         ]),
                         SizedBox(height: 2),
                         Row(children: [
                           Flexible(
                               flex: 2500,
                               child: Row(children: [
                                 Icon(Icons.check_circle,
                                     color: Colors.green, size: 14),
                                 SizedBox(width: 5),
                                 Text('Veg Thaliya',
                                     style: TextStyle(
                                       color: Colors.black,
                                       fontSize: 14,

                                     ))
                               ])),
                           Flexible(
                               flex: 700,
                               child: Row(children: [
                                 Text('X',
                                     style: TextStyle(
                                       color: Colors.grey,
                                       fontSize: 14,

                                     )),
                                 Text('1',
                                     style: TextStyle(
                                       color: Colors.grey,
                                       fontSize: 12,

                                     ))
                               ])),
                           Flexible(
                               flex: 0,
                               child: Text('\u20B9 2000',
                                   style: TextStyle(
                                     color: Colors.grey,
                                     fontSize: 12,

                                   )))
                         ]),
                         SizedBox(height: 3),
                         Divider(color: Colors.grey.withOpacity(0.2)),
                         Row(children: [
                           Flexible(
                               flex: 2500,
                               child: Row(
                                   mainAxisAlignment:
                                   MainAxisAlignment.spaceBetween,
                                   children: [
                                     Row(children: [
                                       Text('Paid',
                                           style: TextStyle(
                                             color: Colors.deepOrange,
                                             fontSize: 14,
                                           )),
                                       SizedBox(width: 3),
                                       Text('(Collect)',
                                           style: TextStyle(
                                             color: Colors.black,
                                             fontSize: 12,

                                           ))
                                     ]),
                                     Row(children: [
                                       Text('Total',
                                           style: TextStyle(
                                             color: Colors.grey,
                                             fontSize: 14,
                                           )),
                                       SizedBox(width: 3),
                                       GestureDetector(
                                           key: _infoKey[index],
                                           onTap: () {
                                             RenderBox renderBox =
                                             _infoKey[index]
                                                 .currentContext
                                                 .findRenderObject();
                                             Offset offset =
                                             renderBox.localToGlobal(
                                                 Offset.zero);
                                             showPopupWindow(
                                                 context: context,
                                                 fullWidth: false,
                                                 //isShowBg:true,
                                                 position: RelativeRect
                                                     .fromLTRB(
                                                     0,
                                                     offset.dy +
                                                         renderBox
                                                             .size
                                                             .height,
                                                     0,
                                                     0),
                                                 child: GestureDetector(
                                                     onTap: () {},
                                                     child: Container(
                                                         padding:
                                                         EdgeInsets
                                                             .all(10),
                                                         child: Column(
                                                             children: [
                                                               Row(
                                                                   mainAxisAlignment:
                                                                   MainAxisAlignment.spaceBetween,
                                                                   children: [
                                                                     Text('Item Total',
                                                                         style: TextStyle(
                                                                           color: Colors.grey,
                                                                           fontSize: 12,

                                                                         )),
                                                                     Text('00',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 14,

                                                                         ))
                                                                   ]),
                                                               SizedBox(height: 3),
                                                               Row(
                                                                   mainAxisAlignment:
                                                                   MainAxisAlignment.spaceBetween,
                                                                   children: [
                                                                     Text('Service Tax',
                                                                         style: TextStyle(
                                                                           color: Colors.grey,
                                                                           fontSize: 12,

                                                                         )),
                                                                     Text('00',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 14,

                                                                         ))
                                                                   ]),
                                                               SizedBox(height: 3),
                                                               Row(
                                                                   mainAxisAlignment:
                                                                   MainAxisAlignment.spaceBetween,
                                                                   children: [
                                                                     Text('Delivery Charge',
                                                                         style: TextStyle(
                                                                           color: Colors.grey,
                                                                           fontSize: 12,

                                                                         )),
                                                                     Text('00',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 14,

                                                                         ))
                                                                   ]),
                                                               SizedBox(height: 3),
                                                               Row(
                                                                   mainAxisAlignment:
                                                                   MainAxisAlignment.spaceBetween,
                                                                   children: [
                                                                     Text('Discount',
                                                                         style: TextStyle(
                                                                           color: Colors.grey,
                                                                           fontSize: 12,

                                                                         )),
                                                                     Text('00',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 14,

                                                                         ))
                                                                   ]),
                                                               SizedBox(height: 3),
                                                               Row(
                                                                   mainAxisAlignment:
                                                                   MainAxisAlignment.spaceBetween,
                                                                   children: [
                                                                     Text('CGST',
                                                                         style: TextStyle(
                                                                           color: Colors.grey,
                                                                           fontSize: 12,

                                                                         )),
                                                                     Text('00',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 14,

                                                                         ))
                                                                   ]),
                                                               SizedBox(height: 3),
                                                               Row(
                                                                   mainAxisAlignment:
                                                                   MainAxisAlignment.spaceBetween,
                                                                   children: [
                                                                     Text('SGST',
                                                                         style: TextStyle(
                                                                           color: Colors.grey,
                                                                           fontSize: 12,

                                                                         )),
                                                                     Text('00',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 14,

                                                                         ))
                                                                   ]),
                                                               Divider(color: Colors.green),
                                                               Row(
                                                                   mainAxisAlignment:
                                                                   MainAxisAlignment.spaceBetween,
                                                                   children: [
                                                                     Text('TOTAL',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 12,
                                                                         )),
                                                                     Text('00',
                                                                         style: TextStyle(
                                                                           color: Colors.black,
                                                                           fontSize: 16,
                                                                           fontWeight: FontWeight.bold,

                                                                         ))
                                                                   ])
                                                             ]))));
                                           },
                                           child: Icon(
                                               Icons.info_outline,
                                               size: 20,
                                               color: Colors.blue)),
                                       SizedBox(width: 3)
                                     ])
                                   ])),
                           Flexible(
                               flex: 700,
                               child: Row(children: [
                                 Text('X',
                                     style: TextStyle(
                                       color: Colors.grey,
                                       fontSize: 14,

                                     )),
                                 Text('2',
                                     style: TextStyle(
                                       color: Colors.grey,
                                       fontSize: 12,

                                     ))
                               ])),
                           Flexible(
                               flex: 0,
                               child: Text('\u20B9 6000',
                                   style: TextStyle(
                                     color: Colors.black,
                                     fontSize: 14,

                                   )))
                         ]),
                         SizedBox(height: 15),
                         Row(
                             mainAxisAlignment:
                             MainAxisAlignment.spaceBetween,
                             children: [
                               Row(children: [
                                 IntrinsicWidth(
                                     child: Column(children: [
                                       Text('REJECT',
                                           style: TextStyle(
                                             color: Colors.black,
                                             fontSize: 12,

                                           )),
                                       SizedBox(height: 1),
                                       Container(
                                           color: Colors.black, height: 1)
                                     ])),
                                 SizedBox(width: 20),
                                 IntrinsicWidth(
                                     child: Column(children: [
                                       Text('BILL',
                                           style: TextStyle(
                                             color: Colors.black,
                                             fontSize: 12,

                                           )),
                                       SizedBox(height: 1),
                                       Container(
                                           color: Colors.black, height: 1)
                                     ]))
                               ]),
                               Container(
                                   decoration: new BoxDecoration(
                                     color: Colors.green,
                                     borderRadius:
                                     BorderRadius.circular(5.0),
                                   ),
                                   padding: EdgeInsets.all(8),
                                   child: Text('FOOD READY',
                                       style: TextStyle(
                                           color: Colors.white,

                                           fontSize: 12)))
                             ])
                       ])))

               ;
             }),
       ),
     ),
   );
  }
  
}

 

 

Show popup window on tap on Guester event by calling the below code

showPopupWindow()

 

Step 4: Run application and see the Popup window on tap

 

flutter Popup window inside listview items

 

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

2303 Views