为什么 Flexible widget 填充所有可用的 space 尽管它的内容更小?
Why Flexible widget filling all the available space despite its content being smaller?
我设计的布局分为两部分:-
1.Horizontal Lisview固定在顶部
2.Vertical 其余布局的滚动视图
我希望 Horizontal Lisview 只占用 space 覆盖其 content.That 所需的部分,这就是我将其放入灵活小部件的原因。
我希望 Vertical Scrollview 填充所有可用的剩余部分 space.That 这就是为什么我将它放在 Expandable 小部件中的原因。
我的布局是这样的:-
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: NotificationListener<ScrollEndNotification>(
child: ListView(
scrollDirection: Axis.horizontal,
controller: _scrollController,
children: moduleList
.map((module) => moduleTemplate(module))
.toList(),
),
onNotification: (t) {
if (_scrollController.position.pixels != 0) {
setState(() {
isScrolledToEnd = true;
});
} else {
setState(() {
isScrolledToEnd = false;
});
}
// allow the notification to continue to be dispatched to further ancestors.
return true;
}),
),
]),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...
]),
],
),
),
),
)
],
),
),
)
],
));
// 列表项
Widget moduleTemplate(module) {
return Container(
margin: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
...
],
),
);
}
当我使用 运行 代码时,我看到我的 Flexible 和 Expandable 小部件都占据了屏幕的一半,因此我在布局的第一部分看到很多空 space,其中仅包含水平列表视图。
我的期望是我的布局的第一部分只会占用 space 它需要显示其内容,因为它被放置在默认情况下 FIT 值为 Loose 的 Flexible 小部件内。
要解决这个问题,我必须指定 flex 值来解决这个问题,但根据屏幕尺寸,它可能会溢出 layout.Hence 的顶部我想解决这个问题而不使用 flex.Why 我的顶部布局占据了一半的屏幕和有没有更好的修复方法?
简而言之,我没有 flex 值的输出看起来像屏幕被平分为两部分..第一部分在顶部有水平列表视图,其余部分 space 是空的..第二部分有 SingleChildScrollView..我想将 SingleChildScrollView 立即底部对齐到列表视图,删除未占用的空白 space
我不确定为什么您的代码没有按预期工作,但这应该可以实现您想要的结果:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
Widget moduleTemplate(module) {
return Container(
margin: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.pink,
)
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Demo"),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(5, (index) => null)
.map((module) => moduleTemplate(module))
.toList(),
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 100,
height: 100,
color: Colors.blue,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.red,
),
],
),
],
),
),
),
],
),
);
}
}
黑色容器是水平滚动视图,有5个粉色框,其余是垂直滚动视图。我不得不多次实施与此类似的方法,每次将 SingleChildScrollView
与 Row
结合使用都会获得更好的结果,而且效果很好。我确定有一种方法可以使 ListView
也能正常工作,但在这种情况下,似乎 ListView
可以毫无问题地替换为 SingleChildScrollView
。
我设计的布局分为两部分:-
1.Horizontal Lisview固定在顶部
2.Vertical 其余布局的滚动视图
我希望 Horizontal Lisview 只占用 space 覆盖其 content.That 所需的部分,这就是我将其放入灵活小部件的原因。 我希望 Vertical Scrollview 填充所有可用的剩余部分 space.That 这就是为什么我将它放在 Expandable 小部件中的原因。
我的布局是这样的:-
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: NotificationListener<ScrollEndNotification>(
child: ListView(
scrollDirection: Axis.horizontal,
controller: _scrollController,
children: moduleList
.map((module) => moduleTemplate(module))
.toList(),
),
onNotification: (t) {
if (_scrollController.position.pixels != 0) {
setState(() {
isScrolledToEnd = true;
});
} else {
setState(() {
isScrolledToEnd = false;
});
}
// allow the notification to continue to be dispatched to further ancestors.
return true;
}),
),
]),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...
]),
],
),
),
),
)
],
),
),
)
],
));
// 列表项
Widget moduleTemplate(module) {
return Container(
margin: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
...
],
),
);
}
当我使用 运行 代码时,我看到我的 Flexible 和 Expandable 小部件都占据了屏幕的一半,因此我在布局的第一部分看到很多空 space,其中仅包含水平列表视图。 我的期望是我的布局的第一部分只会占用 space 它需要显示其内容,因为它被放置在默认情况下 FIT 值为 Loose 的 Flexible 小部件内。 要解决这个问题,我必须指定 flex 值来解决这个问题,但根据屏幕尺寸,它可能会溢出 layout.Hence 的顶部我想解决这个问题而不使用 flex.Why 我的顶部布局占据了一半的屏幕和有没有更好的修复方法?
简而言之,我没有 flex 值的输出看起来像屏幕被平分为两部分..第一部分在顶部有水平列表视图,其余部分 space 是空的..第二部分有 SingleChildScrollView..我想将 SingleChildScrollView 立即底部对齐到列表视图,删除未占用的空白 space
我不确定为什么您的代码没有按预期工作,但这应该可以实现您想要的结果:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
Widget moduleTemplate(module) {
return Container(
margin: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.pink,
)
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Demo"),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(5, (index) => null)
.map((module) => moduleTemplate(module))
.toList(),
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 100,
height: 100,
color: Colors.blue,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.red,
),
],
),
],
),
),
),
],
),
);
}
}
黑色容器是水平滚动视图,有5个粉色框,其余是垂直滚动视图。我不得不多次实施与此类似的方法,每次将 SingleChildScrollView
与 Row
结合使用都会获得更好的结果,而且效果很好。我确定有一种方法可以使 ListView
也能正常工作,但在这种情况下,似乎 ListView
可以毫无问题地替换为 SingleChildScrollView
。