SePröbläm
SePröbläm

Reputation: 5739

How to prevent Flutter from clipping BoxDecoration shadows?

Here's a screenshot of a simple flutter app:

enter image description here

Pushing the ++/-- buttons adds/removes a panel to/from a Container. The container is outlined with a blue shadow. Now, as soon as the container grows too close to the bottom border, it's shadow gets clipped on the left and right border.

Do you have any ideas what causes the clipping and how to avoid it?

This is how the code looks:

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> {
  int _counter = 0;
  ScrollController _scrollController;

  @override
  void initState() {
    _scrollController = ScrollController();
    super.initState();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  void _decrementCounter() {
    setState(() {
      if (_counter > 0) {
        _counter--;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(20),
        child: ListView(
          controller: _scrollController,
          children: <Widget>[
            Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                SizedBox(height: 30),
                _getButtonPanel(),
                SizedBox(height: 20),
                Container(
                  padding: EdgeInsets.all(20),
                  child: _getChildren(_counter),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.all(Radius.circular(20)),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.blue,
                        offset: Offset(0, 0),
                        blurRadius: 10.0,
                        spreadRadius: 5.0,
                      )
                    ],
                  ),
                ),
                SizedBox(height: 20),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _getButtonPanel() {
    return Row(
      mainAxisSize: MainAxisSize.max,
      children: <Widget>[
        OutlineButton(
          onPressed: _decrementCounter,
          child: Text('--'),
        ),
        Spacer(),
        OutlineButton(
          onPressed: _incrementCounter,
          child: Text('++'),
        ),
      ],
    );
  }

  Widget _getChildren(int cnt) {
    List<Widget> children = [];
    for (int i = 0; i < cnt; i++) {
      children.add(_getItem(1 + i));
    }

    return Column(
      children: children,
    );
  }

  Widget _getItem(int i) {
    return Column(
      children: <Widget>[
        SizedBox(
          height: 50,
        ),
        Text('Child panel $i'),
        SizedBox(
          height: 50,
        ),
      ],
    );
  }
}

Upvotes: 2

Views: 3694

Answers (1)

Nehal
Nehal

Reputation: 1489

You should add margin to the container containing the list to prevent it from clipping.

    Container(
      padding: EdgeInsets.all(20),
      margin: EdgeInsets.all(15), //Add margin
      child: _getChildren(_counter),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(20)),
        boxShadow: [
          BoxShadow(
            color: Colors.blue,
            offset: Offset(0, 0),
            blurRadius: 10.0,
            spreadRadius: 5.0,
          )
        ],
      ),
    );

Upvotes: 3

Related Questions