Я пытаюсь сделать прокручиваемый пользовательский интерфейс во флаттере. Ну, я добавил 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;
}
Есть проблема, ниже вывод
Вы можете увидеть это после вершины фоновое изображение, нет контента. Контейнер с верхним фоновым изображением составляет 30% от высоты. все, что не находится в пределах его области, не будет отображаться. Однако, если вы увеличите его высоту, отобразится остальная часть содержимого, а также увеличится размер фонового изображения.
Что здесь не так? Как отобразить содержимое ниже 30% высоты без проблем?
Также обратите внимание, что у меня есть еще один ListView
в конце кода. Я не хочу, чтобы этот ListView
сам прокручивал, потому что верхний ListView
выполняет работу по прокрутке полной страницы.