我以前使用过带有固定和可滚动部分的页面,并且总是很挣扎并且尝试过错误,可能不会产生最佳解决方案。这次我决定研究一下,希望找到正确的方法,所以我编写了一个小测试程序来稍微模拟我的应用程序。
使用的组件基本上是:
Scaffold:
body: Column
Widgets
Expanded
child: RawScrollbar
child: SingleChildScrollView
child: Row
children: Column
children: Widgets
在我看来,这是解决问题的一种方法。看起来有很多 Widget,但如果这是最好的解决方案,那么一旦知道它,就是这样。
我的问题是,有没有更好的方法来解决这个问题?
我的测试应用程序如下:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage();
@override
State<MyHomePage> createState() => _MyHomePage();
}
class _MyHomePage extends State<MyHomePage> {
final ScrollController _wScrollController = ScrollController();
final TextStyle _wStyle = TextStyle(fontSize: 24, color: Colors.blue);
//
@override
void dispose() {
_wScrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text('Scrolling Test'),
centerTitle: true,
),
body: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
SizedBox(height: 20),
SizedBox(height: 100, child: Text('Page Heading', style: _wStyle)),
Icon(Icons.directions_boat_filled_rounded,
size: 100, color: Colors.blue),
SizedBox(height: 25),
Text(style: _wStyle, "Select Option"),
SizedBox(height: 20),
Expanded(
child: RawScrollbar(
thumbVisibility: true,
thumbColor: Colors.blueGrey[100],
shape: const StadiumBorder(),
thickness: 12,
padding: EdgeInsets.only(left: 2),
minThumbLength: 100,
scrollbarOrientation: ScrollbarOrientation.right,
controller: _wScrollController,
child: SingleChildScrollView(
primary: false,
controller: _wScrollController,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children:
_fnCreateButtons(10) /* LIST OF BUTTONS */,
)
]))))
]));
}
//==== FUNCTION - CREATE LIST OF BUTTONS ====//
List<Widget> _fnCreateButtons(int iCount) {
List<Widget> lswButtons = [];
for (int iNdx = 0; iNdx < iCount; iNdx++) {
lswButtons.add(SizedBox(
height: 100,
child: ElevatedButton(
onPressed: () {}, child: Text('Selection ${iNdx + 1}'))));
}
return lswButtons;
}
}
我认为你的解决方案看起来不错。
除了一点。我更喜欢使用 ListView.builder 而不是 SingleChildScrollView。 ListView.builder 擅长构建项目以在需要时显示。 SingleChildScrollView 一次构建所有项目。创建 10 个按钮是可以的,但如果必须创建 1000 个按钮,那么就会出现性能问题。
从 UI/UX 角度来看,添加 RawScrollbar 是一个很好的解决方案