akshathjain / sliding_up_panel

A draggable Flutter widget that makes implementing a SlidingUpPanel much easier!
https://pub.dartlang.org/packages/sliding_up_panel
Other
1.38k stars 378 forks source link

body out of panel! #196

Closed hewa-jalal closed 2 years ago

hewa-jalal commented 4 years ago

i am having a very weird problem with the panel and that's the body is being displayed outside, like this off5ZZIl1n here is the code

where I use the panel:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final Completer<GoogleMapController> _controller = Completer();
  static const _center = LatLng(45.521563, -122.67433);
  final LatLng _lastMapPosition = _center;
  final _pc = PanelController();

  _onMapCreated(GoogleMapController controller) {
    _controller.complete(controller);
  }

  // _onCameraMove(CameraPosition position) {
  //     _lastMapPosition = position.target;
  // }

  @override
  Widget build(BuildContext context) {
    ScreenUtil.init(context);
    return Scaffold(
      backgroundColor: Colors.black,
      drawer: CustomDrawer(),
      body: Container(
        color: Colors.grey,
        child: Stack(
          children: <Widget>[
            RaisedButton(
              child: Text('Open Dialog'),
              onPressed: () => CoolAlert.show(
                context: context,
                type: CoolAlertType.info,
                title: 'No nearby drivers',
                text: 'Please call for a driver now, 9085095433',
              ),
            ),
            Positioned(
              top: 0.08.hp,
              left: 0.10.wp,
              child: Container(
                width: 0.8.wp,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(35),
                    bottomRight: Radius.circular(45),
                    bottomLeft: Radius.circular(35),
                  ),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.5),
                      spreadRadius: 4,
                      blurRadius: 7,
                      offset: Offset(0, 3),
                    ),
                  ],
                ),
                padding: EdgeInsets.symmetric(
                  vertical: 12,
                  horizontal: 10,
                ),
                child: Padding(
                  padding: const EdgeInsets.only(left: 12.0),
                  child: Row(
                    children: [
                      Icon(
                        Icons.circle,
                        size: 10,
                        color: appBlue,
                      ),
                      SizedBox(width: 0.02.wp),
                      Text(
                        'Your Taxi has arrived',
                        style: GoogleFonts.hammersmithOne(
                          fontSize: 45.sp,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
            GoogleMap(
              // onMapCreated: _onMapCreated,
              initialCameraPosition: CameraPosition(
                target: _center,
                zoom: 11.0,
              ),
            ),
            SlidingUpPanel(
              controller: _pc,
              panel: NavigateHeader(),
              body: NavigateBody(),
              // isDraggable: false,
              color: Colors.transparent,
              boxShadow: null,
              minHeight: 0.30.hp,
            ),
          ],
        ),
      ),
    );
  }
}

and the body code:

class NavigateBody extends StatelessWidget {
  final _navigationService = NavigatorService.make();

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          BottomSheetTile(
            onTap: () => _navigationService.navigateTo(HomeAddressPage.tag),
            leading: Icon(Icons.house),
            title: 'Set Home Address',
          ),
          BottomSheetTile(
            onTap: () => _navigationService.navigateTo(WorkAddressPage.tag),
            leading: Icon(Icons.work),
            title: 'Set Work Address',
          ),
          BottomSheetTile(
            onTap: () => _navigationService.navigateTo(SelectAddressPage.tag),
            leading: Icon(Icons.location_city_rounded),
            title: 'Select from saved places',
          ),
        ],
      ),
    );
  }
}

BottomSheetTile

class BottomSheetTile extends StatelessWidget {
  final String title;
  final Widget leading;
  final VoidCallback onTap;

  BottomSheetTile({
    Key key,
    this.title,
    this.leading,
    this.onTap,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: onTap,
      leading: leading,
      title: Text(
        title,
        style: GoogleFonts.roboto(
          color: Colors.blue,
          fontSize: 20,
          fontWeight: FontWeight.w700,
        ),
      ),
      trailing: Icon(Icons.arrow_forward_sharp),
    );
  }
}
ad-belikov commented 4 years ago

A similar problem. The floor panel is a MAPBOX card. The map considers its vertical size to be larger than the screen size of the device. You can see that the center of the map, marked in red, is shifted down.

In the second picture, the same map, in the same container, but without sliding_up_panel. The center is located correctly. SmartSelect_20201006-143045 SmartSelect_20201006-143006

hewa-jalal commented 4 years ago

hey @adbelikov, for now, i just used the panel as for the body widget and used collapsed for the header and it works fine. but i still don't know what is the purpose of body property.

ruehl commented 4 years ago

I have the same problem as mentioned by @adbelikov. As soon as I use the SlidingUpPanel widget in my scaffold (as outlined in the guide), the center of the body widget seems to be shifted downwards.

I checked with the source code and found out that the body widget (if specified) is put into a Container widget, whose height is derived from the screen height per MediaQuery. This is fine as long as there is (for example) no AppBar, whose height actually had to be taken into consideration during calculation of the container's height.

https://github.com/akshathjain/sliding_up_panel/blob/14705a7/lib/src/panel.dart#L265-269

In my case, when I remove the AppBar of my Scaffold (while Slide Panel in place), the center gets correctly aligned with the center of the screen. This is because the height available to the body equals to the full size of the screen as reported by the MediaQuery.

ncuillery commented 3 years ago

Same issue here, in addition to the AppBar, I have a BottomNavigationBar that makes things worse (the center is shifted down because of the AppBar AND the bottom of the map is hidden by the BottomNavigationBar)

ncuillery commented 3 years ago

92 should help, right?

In the meantime, as a workaround, I have removed the body and wrapped the SlidingUpPanel in a Stack with the former body below.

Before

SlidingUpPanel(
  header: MyHeader(),
  panel: MyPanel(),
  body: MyMap(),
),

After

Stack(
  children: [
    MyMap(),
    SlidingUpPanel(
      header: MyHeader(),
      panel: MyPanel(),
    ),
  ],
),
Shewebi commented 3 years ago

My workaround is to keep the SlidingUpPanel and wrapping it with a MediaQuery.

So you go from this:

SlidingUpPanel(
   child: MyMap(),
   header: MyHeader(),
   panel: MyPanel(),
   ...
)

To this:

LayoutBuilder(
   builder: (_, constraints) {
      final mediaQueryData = MediaQuery.of(context);

      return MediaQuery(
         data: mediaQueryData.copyWith(
            size: constraints.biggest,
         ),
         child: SlidingUpPanel(
            /// Optionally you can then wrap the body with another [MediaQuery] and the
            /// original [MediaQueryData] to prevent unexpected behaviour due to the now
            /// incorrect [MediaQuery.size]
            body: MediaQuery(
               data: mediaQueryData,
               child: MyMap(),
            ),
            header: MyHeader(),
            panel: MyPanel(),
            ...
         )
      )
   }
)
renoinn commented 3 years ago

@Shewebi work fine for me! thank you :)

Wiesmak commented 2 years ago

@Shewebi you saved my day, thanks!