1

I would like to create my own safe area view but instead of just cutting off the overflown area, I would like to have the overflowing area blocked by a semi transparent background.

I realise this question is somewhat similar to Allowing a widget to overflow to another widget but the answer there can solve that question in particular but not mine.

So how do I make the flutter widget overflow?

I used stack to place a container above the view when there's a top overflow and below if there's a bottom overflow. The result works good except that its overflowing to the semi transparent background.

screenshot

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Didian',
      home: Scaffold(
        body: OpacitySafeArea(
          child: RandomWords()
        ),
      ),
    );
  }
}

class OpacitySafeArea extends StatelessWidget {
  final Widget child;
  OpacitySafeArea({
    @required this.child
  });

  @override
  Widget build(BuildContext context) {
    var deviceData = MediaQuery.of(context);
    var height = deviceData.size.height;
    var width = deviceData.size.width;
    var top = deviceData.padding.top;
    var bottom = deviceData.padding.bottom;
    print(deviceData);
    return Stack(
      overflow: Overflow.visible,
      children: <Widget>[
        this.child,
        top > 0? Container(
          color: Color.fromRGBO(255, 255, 255, 0.9),
          height: top,
          width: width
        ):null,
        bottom > 0? Positioned(
          bottom: 0,
          child: Container(
            color: Color.fromRGBO(255, 255, 255, 0.9),
            height: bottom,
            width: width
          )
        ):null
      ].where((child) => child != null).toList()
    );
  }
}

class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];

  Widget buildSuggestions() {
    return ListView.separated(
      padding: EdgeInsets.all(16),
      itemCount: 100,
      itemBuilder: (context, index) {
        if(index >= _suggestions.length) {
          _suggestions.add(WordPair.random());
        }
        return ListTile(
          title: Text(
            _suggestions[index].asPascalCase,
            style: TextStyle(fontSize: 18)
          )
        );
      },
      separatorBuilder: (context, index) => Divider(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return buildSuggestions();
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}
2
  • Overflow is anti-pattern in Flutter. Don't. Instead just remove that SafeArea, this will allow the list to display content behind the top/bottom. Commented Oct 21, 2019 at 8:08
  • 1
    Without the SafeArea, the device status bar and menu bar will interfere with the content or the content will just disappear without a proper transition. Or else I will need to put a shadow or a border to indicate the SafeArea, but this is a style preference. Commented Oct 21, 2019 at 8:42

1 Answer 1

1

I was looking for same, and finally used a simple solution without using SafeArea():

Just apply a padding to ListView itself, which you can get using MediaQuery.of(context).viewPadding.bottom

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        padding: EdgeInsets.all(0).copyWith(bottom: MediaQuery.of(context).viewPadding.bottom),
        itemCount: 2000,
        itemBuilder: (BuildContext context, int index) {
            return Text("Item: $index");
        },
      ),
    );
  }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.