[Flutter]-只显示一个widget在屏幕上可见的部分

[Flutter]-Display only the visible parts of a widget in the screen

我创建了一个布局与线框几乎相同的屏幕。下面是我创建的屏幕。

我希望它看起来像这样,圆圈与屏幕相交并且屏幕只显示不是 intersected.For 圆圈的部分我正在使用一个名为 shape_of_view.How 我可以让 ui 中的圆圈看起来像线框中的圆圈吗?

下面是我的全屏代码,

@override
Widget build(BuildContext context) {
final TextEditingController _search = TextEditingController();
return Scaffold(
  resizeToAvoidBottomInset: false,
  body: _isloading
      ? Center(child: CircularProgressIndicator())
      : content(context, _search),
  bottomNavigationBar: BottomNavigationBar(
    items: const <BottomNavigationBarItem>[
      BottomNavigationBarItem(
        icon: Icon(Icons.call),
        label: 'Calls',
      ),
      BottomNavigationBarItem(
        icon: Icon(Icons.camera),
        label: 'Camera',
      ),
      BottomNavigationBarItem(
        icon: Icon(Icons.chat),
        label: 'Chats',
      ),
    ],
  ),
);
}

Widget content(BuildContext context, TextEditingController _search) {
return Stack(
  children: [
    Padding(
      padding: const EdgeInsets.only(bottom: 750.0),
      child: Positioned.fill(
          child: Align(
              alignment: Alignment.topRight,
              child: circle(context, MediaQuery.of(context).size.width * 0.4))),
    ),
    Padding(
      padding: const EdgeInsets.only(bottom: 280.0),
      child: circle(context, MediaQuery.of(context).size.width * 0.7),
    ),
    Padding(padding: const EdgeInsets.only(top: 500.0),
      child: Positioned.fill(
          child: Align(
              alignment: Alignment.bottomRight,
              child: circle(context, MediaQuery.of(context).size.width * 0.9))),
    ),
    Padding(
      padding: const EdgeInsets.only(top: 130.0),
      child: Column(
        children: [
          homeTop(context, _search),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8.0),
            child: coupon(context),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 50.0),
            child: category(context),
          )
        ],
      ),
    ),
  ],
);
}

Widget homeTop(BuildContext context, TextEditingController _search) {
return Padding(
  padding: const EdgeInsets.symmetric(horizontal: 16.0),
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Container(
        child: Column(
          children: [
            Text(
              "Good Morning John,",
            ),
            Text("Checkout what you like"),
          ],
        ),
      ),
      Padding(
        padding: const EdgeInsets.symmetric(vertical: 20.0),
        child: SearchBar(),
      )
    ],
  ),
);
}

Widget category(BuildContext context) {
var size = MediaQuery.of(context).size;
final double itemHeight = (size.height) / 7;
final double itemWidth = size.width / 2;
return Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text("Categories"),
          Text("see all"),
        ],
      ),
    ),
    Container(
      height: 300,
      child: GridView.count(
        childAspectRatio: (itemWidth / itemHeight),
        primary: false,
        padding: const EdgeInsets.all(20),
        crossAxisSpacing: 3,
        mainAxisSpacing: 3,
        crossAxisCount: 2,
        children: <Widget>[
          CategoryCard(title: "Spa Treatments"),
          CategoryCard(title: "Barbers"),
          CategoryCard(title: "Doctors Appointment"),
          CategoryCard(title: "Restaurant"),
        ],
      ),
    ),
  ],
);
}

Widget coupon(BuildContext context) {
return SizedBox(
    height: MediaQuery.of(context).size.height * 0.2,
    child: Card(
        color: cardColor,
        child: Row(
          children: [
            Column(
              children: [
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                      width: MediaQuery.of(context).size.width * 0.4,
                      child: Text(
                          "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cursus sed eros ullamcorper.")),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text("*Conditions Apply"),
                )
              ],
            ),
            Spacer(),
            Container(
                width: MediaQuery.of(context).size.width * 0.5,
                height: MediaQuery.of(context).size.height * 0.2,
                child: ShapeOfView(
                  shape: ArcShape(
                      direction: ArcDirection.Outside,
                      height: 50,
                      position: ArcPosition.Left),
                  child: Container(
                    color: Colors.amber,
                  ),
                )
                )
          ],
        )));
           }

        Widget circle(BuildContext context, double width) {
        return ShapeOfView(
         width: width,
           shape: CircleShape(
          ),
          child: Container(
          color: lightTheme_Ascent,
         ),
        );
         }

使用 Stack 小部件包装您的 body 属性。你不需要任何包来创建一个圆圈。只需使用容器小部件,并在其装饰中使用 属性 到 BoxShape.circle 的形状。并使用 Positioned 将此小部件定位在您的 UI.

Container(
          decoration: const BoxDecoration(
            color: Colors.grey,
            shape: BoxShape.circle
          ),
        ),