Flutter: `Stack` не отображает контент, который находится за пределами области его первого виджета - PullRequest
0 голосов
/ 15 февраля 2020

Я пытаюсь сделать прокручиваемый пользовательский интерфейс во флаттере. Ну, я добавил ListView, а затем внутри него Stack. Ниже мой код

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

import 'package:flutter/widgets.dart';

var scaffoldKey = GlobalKey<ScaffoldState>();

class TestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      drawer: Drawer(
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: <Widget>[
            DrawerHeader(
              child: Text('Drawer Header'),
              decoration: BoxDecoration(
                color: Colors.blue,
              ),
            ),
            ListTile(
              title: Text('Item 1'),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              title: Text('Item 2'),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
      body: Container(
        height: double.infinity,
        child: ListView(
          shrinkWrap: true,
          children: <Widget>[TestPageUI()],
        ),
      ),
      key: scaffoldKey,
    );
  }
}

class TestPageUI extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return TestPageState();
  }
}

class TestPageState extends State<TestPageUI> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
          height: MediaQuery.of(context).size.height * .30,
          width: double.infinity,
          child: ClipPath(
            clipper: ClippingClass(),
            child: Container(
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height * .30,
              decoration: BoxDecoration(
                  image: DecorationImage(
                      fit: BoxFit.cover,
                      image: AssetImage("assets/images/morning_image.png"))),
            ),
          ),
        ),
        SafeArea(
          child: Row(
            children: <Widget>[
              IconButton(
                icon: Icon(
                  Icons.menu,
                  color: Colors.white,
                ),
                onPressed: () {
                  print("clicked");
                  scaffoldKey.currentState.openDrawer();
                },
              ),
              Spacer(
                flex: 2,
              ),
              IconButton(
                icon: Icon(
                  Icons.notifications,
                  color: Colors.white,
                ),
                onPressed: () {},
              ),
            ],
          ),
        ),
        Positioned(
          top: MediaQuery.of(context).size.height * .2,
          left: 0.0,
          right: 0.0,
          child: Align(
            alignment: Alignment.center,
            child: Container(
              child: Text(
                "Good Morning, Fred",
                style: Theme.of(context)
                    .textTheme
                    .headline
                    .apply(color: Colors.white),
              ),
            ),
          ),
        ),
        Positioned(
          top: MediaQuery.of(context).size.height * .3,
          left: 0.0,
          right: 0.0,
          child: Container(
            margin: EdgeInsets.only(left: 10, right: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Container(
                  width: MediaQuery.of(context).size.width * .22,
                  height: 100,
                  child: Column(
                    children: <Widget>[
                      Image.asset(
                        "assets/icons/car_service.png",
                        width: 48,
                        height: 48,
                      ),
                      Container(
                        margin: EdgeInsets.all(5),
                        child: Text(
                          "ONE",
                          style: Theme.of(context)
                              .textTheme
                              .caption
                              .apply(color: Colors.black),
                          textAlign: TextAlign.center,
                        ),
                      )
                    ],
                  ),
                ),
                Spacer(
                  flex: 1,
                ),
                Container(
                  width: MediaQuery.of(context).size.width * .22,
                  height: 100,
                  child: Column(
                    children: <Widget>[
                      Image.asset(
                        "assets/icons/car_service.png",
                        width: 48,
                        height: 48,
                      ),
                      Container(
                        margin: EdgeInsets.all(5),
                        child: Text(
                          "FOUR",
                          style: Theme.of(context)
                              .textTheme
                              .caption
                              .apply(color: Colors.black),
                          textAlign: TextAlign.center,
                        ),
                      )
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
        Positioned(
          top: MediaQuery.of(context).size.height * .54,
          left: 0.0,
          right: 0.0,
          child: Container(
            height: MediaQuery.of(context).size.height,
            child: ListView.builder(
              itemCount: 100,
              itemBuilder: (BuildContext context, int index) {
                return Container(
                  margin: EdgeInsets.only(bottom: 10, left: 10, right: 10),
                  child: _createAdvertisement(),
                );
              },
            ),
          ),
        )
      ],
    );
  }

  Widget _createAdvertisement() {
    return Card(
      elevation: 4.0,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
      clipBehavior: Clip.antiAlias,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          FadeInImage.assetNetwork(
            alignment: Alignment.topCenter,
            placeholder: "https://picsum.photos/200",
            image: "https://picsum.photos/200",
            fit: BoxFit.fill,
            width: double.infinity,
            height: MediaQuery.of(context).size.height * .9 / 4,
          ),


        ],
      ),
    );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }
}

class ClippingClass extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    path.lineTo(0.0, size.height);
    path.quadraticBezierTo(
        size.width / 4, size.height - 30, size.width / 2, size.height - 30);
    path.quadraticBezierTo(size.width - (size.width / 4), size.height - 30,
        size.width, size.height);
    path.lineTo(size.width, 0.0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

Есть проблема, ниже вывод

enter image description here

Вы можете увидеть это после вершины фоновое изображение, нет контента. Контейнер с верхним фоновым изображением составляет 30% от высоты. все, что не находится в пределах его области, не будет отображаться. Однако, если вы увеличите его высоту, отобразится остальная часть содержимого, а также увеличится размер фонового изображения.

Что здесь не так? Как отобразить содержимое ниже 30% высоты без проблем?

Также обратите внимание, что у меня есть еще один ListView в конце кода. Я не хочу, чтобы этот ListView сам прокручивал, потому что верхний ListView выполняет работу по прокрутке полной страницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...