alexlipa
alexlipa

Reputation: 1291

Flutter: Place widget on top of the other with negative positioning

I am trying to implement this modalBottomSheet

enter image description here

and I thought to use Stack with negative positioning

showModalBottomSheet(
    context: context,
    builder: (context) {
        return Stack(
            alignment: AlignmentDirectional.bottomStart,
            children: [
                Container(
                    width: double.infinity,
                    height: 200,
                    color: Colors.white,
                    child: Column(//here there will be the text)
                ),
                Positioned(
                    top: -20,
                    left: 0,
                    right: 0,
                    child: CircleAvatar(
                        backgroundColor: Palette.white,
                        radius: 38,
                        child: CircleAvatar(
                            backgroundImage: NetworkImage(snapshot.data.image),
                            radius: 34,
                            backgroundColor: Palette.white),
                     ),
                 )]);
                 

However this cuts the top part of the CircleAvatar picture (as I kind of expected).

Any idea on how to implement this?

Upvotes: 1

Views: 2836

Answers (2)

KuKu
KuKu

Reputation: 7502

Here is my tricky implementation.

  1. Set bottom sheet's background color to transparent.
  2. Add top margin as avatar's half height to base Container.
  3. Set base container's background color to white
  4. Change the avatar's top position value to 0

enter image description here

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          show();
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  void show() {
    showModalBottomSheet(
        backgroundColor: Colors.transparent,
        context: context,
        builder: (context) {
          return Stack(
            alignment: AlignmentDirectional.bottomStart,
            children: [
              Container(
                width: double.infinity,
                height: 200,
                margin: EdgeInsets.only(top: 35),
                color: Colors.transparent,
                child: Container(
                  padding: EdgeInsets.only(top: 60),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(10),
                      topRight: Radius.circular(10),
                    ),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Text(
                        'Alessandro Liparoti',
                        style: TextStyle(
                          color: Colors.black,
                          fontSize: 25,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      SizedBox(height: 25),
                      Text(
                        '4 games palyed',
                        style: TextStyle(
                          color: Colors.grey,
                          fontSize: 20,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              Positioned(
                top: 0,
                left: 0,
                right: 0,
                child: CircleAvatar(
                  backgroundColor: Colors.white,
                  radius: 38,
                  child: CircleAvatar(
                      backgroundImage: NetworkImage(
                          'https://image.flaticon.com/icons/png/512/147/147144.png'),
                      radius: 34,
                      backgroundColor: Colors.white),
                ),
              ),
            ],
          );
        });
  }
}


Upvotes: 0

Omar Mahmoud
Omar Mahmoud

Reputation: 3087

you need to change the clipBehavior to Clip.none on the Stack

Stack(
    clipBehavior: Clip.none,
...)

Upvotes: 7

Related Questions