Skip to content

Commit 4e70593

Browse files
committed
组件详情页使用 CustomScrollView 优化
1 parent 638e4f4 commit 4e70593

File tree

3 files changed

+177
-164
lines changed

3 files changed

+177
-164
lines changed

lib/app/res/style/unit_text_style.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ import 'unit_color.dart';
44

55
///文本样式
66
class TStyleUnit {
7+
8+
// 标题加黑
9+
static const labelBold = TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
10+
static const commonChip = TextStyle(
11+
fontSize: 12,
12+
color: Colors.white,
13+
);
14+
static const deprecatedChip = TextStyle(
15+
fontSize: 12,
16+
color: Colors.white,
17+
decoration: TextDecoration.lineThrough,
18+
decorationThickness: 2,
19+
);
20+
721
static const lagerTextSize = 30.0;
822
static const bigTextSize = 23.0;
923
static const normalTextSize = 18.0;
Lines changed: 86 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_bloc/flutter_bloc.dart';
3-
import 'package:flutter_star/flutter_star.dart';
43
import 'package:flutter_unit/app/blocs/global/global_bloc.dart';
54
import 'package:flutter_unit/app/blocs/global/global_state.dart';
65
import 'package:flutter_unit/app/res/cons.dart';
6+
import 'package:flutter_unit/app/res/style/unit_text_style.dart';
77
import 'package:flutter_unit/app/res/toly_icon.dart';
88
import 'package:flutter_unit/app/utils/Toast.dart';
9+
import 'package:flutter_unit/components/permanent/code/highlighter_style.dart';
910
import 'package:flutter_unit/components/permanent/feedback_widget.dart';
10-
import 'package:flutter_unit/components/permanent/panel.dart';
1111
import 'package:flutter_unit/components/project/widget_node_panel.dart';
1212
import 'package:flutter_unit/widget_system/blocs/widget_system_bloc.dart';
1313
import 'package:flutter_unit/widget_system/repositories/model/node_model.dart';
1414
import 'package:flutter_unit/widget_system/repositories/model/widget_model.dart';
1515

1616
import '../../widgets/widgets_map.dart';
1717
import 'category_end_drawer.dart';
18+
import 'widget_detail_panel.dart';
1819

1920
class WidgetDetailPage extends StatefulWidget {
2021
final WidgetModel model;
@@ -40,39 +41,62 @@ class _WidgetDetailPageState extends State<WidgetDetailPage> {
4041

4142
@override
4243
Widget build(BuildContext context) {
43-
return Scaffold(
44-
endDrawer: CategoryEndDrawer(widget: _modelStack.last),
45-
appBar: AppBar(
46-
title: Text(_modelStack.last.name),
47-
leading: const BackButton(),
48-
actions: <Widget>[
49-
_buildToHome(),
50-
FeedbackWidget(
51-
onPressed: () => _toggleLikeState(context),
52-
child: BlocConsumer<LikeWidgetBloc, LikeWidgetState>(
53-
listener: _listenLikeStateChange,
54-
builder: _buildByLikeState,
55-
),
56-
)
57-
],
44+
return BlocBuilder<WidgetDetailBloc, DetailState>(
45+
builder: (_, state) => Scaffold(
46+
endDrawer: CategoryEndDrawer(widget: currentWidgetModel),
47+
appBar: AppBar(
48+
title: Text(currentWidgetModel.name),
49+
leading: const BackButton(),
50+
actions: <Widget>[
51+
_buildToHome(),
52+
FeedbackWidget(
53+
onPressed: () => _toggleLikeState(context),
54+
child: BlocConsumer<LikeWidgetBloc, LikeWidgetState>(
55+
listener: _listenLikeStateChange,
56+
builder: _buildByLikeState,
57+
),
58+
)
59+
],
60+
),
61+
body: Builder(builder: (ctx) {
62+
return _buildContent(ctx, state);
63+
}),
5864
),
59-
body: Builder(builder: _buildContent),
6065
);
6166
}
6267

63-
Widget _buildContent(BuildContext context) => WillPopScope(
64-
onWillPop: () => _whenPop(context),
65-
child: SingleChildScrollView(
66-
child: Column(
67-
crossAxisAlignment: CrossAxisAlignment.start,
68-
children: <Widget>[
69-
WidgetDetailTitle(
70-
model: _modelStack.last,
68+
Widget get linkText => Row(
69+
children: const [
70+
Padding(
71+
padding: EdgeInsets.only(left: 15, right: 5),
72+
child: Icon(Icons.link, color: Colors.blue),
73+
),
74+
Text('相关组件', style: TStyleUnit.labelBold),
75+
],
76+
);
77+
78+
Widget _buildContent(BuildContext context, DetailState state) {
79+
return WillPopScope(
80+
onWillPop: () => _whenPop(context),
81+
child: CustomScrollView(
82+
slivers: [
83+
SliverToBoxAdapter(
84+
child: Column(
85+
crossAxisAlignment: CrossAxisAlignment.start,
86+
children: [
87+
WidgetDetailPanel(model: _modelStack.last),
88+
linkText,
89+
if (state is DetailWithData)
90+
_buildLinkTo(context, state.links),
91+
const Divider(),
92+
],
93+
),
7194
),
72-
BlocBuilder<WidgetDetailBloc, DetailState>(builder: _buildDetail)
95+
if (state is DetailWithData)
96+
_buildSliverNodeList(state.nodes, state.widgetModel.name)
7397
],
74-
),
75-
));
98+
));
99+
}
76100

77101
Widget _buildToHome() => Builder(
78102
builder: (ctx) => GestureDetector(
@@ -117,66 +141,24 @@ class _WidgetDetailPageState extends State<WidgetDetailPage> {
117141

118142

119143
void _toggleLikeState(BuildContext context) {
120-
BlocProvider.of<LikeWidgetBloc>(context)
121-
.add(ToggleLikeWidgetEvent(id: currentWidgetModel.id));
122-
}
123-
124-
Widget _buildNodes(List<NodeModel> nodes, String name) {
125-
GlobalState globalState = BlocProvider.of<GlobalBloc>(context).state;
126-
return Column(
127-
children: nodes
128-
.asMap()
129-
.keys
130-
.map((i) => WidgetNodePanel(
131-
codeStyle: Cons.codeThemeSupport.keys.toList()[globalState.codeStyleIndex],
132-
codeFamily: 'Inconsolata',
133-
text: nodes[i].name,
134-
subText: nodes[i].subtitle,
135-
code: nodes[i].code,
136-
show: WidgetsMap.map(name)[i],
137-
))
138-
.toList());
144+
BlocProvider.of<LikeWidgetBloc>(context).add(
145+
ToggleLikeWidgetEvent(id: currentWidgetModel.id),
146+
);
139147
}
140148

141149
Future<bool> _whenPop(BuildContext context) async {
142150
if (Scaffold.of(context).isEndDrawerOpen) return true;
143151
_modelStack.removeLast();
144152
if (_modelStack.isNotEmpty) {
145-
setState(() {
146-
BlocProvider.of<WidgetDetailBloc>(context).add(FetchWidgetDetail(_modelStack.last));
147-
});
153+
BlocProvider.of<WidgetDetailBloc>(context).add(
154+
FetchWidgetDetail(currentWidgetModel),
155+
);
148156
return false;
149157
} else {
150158
return true;
151159
}
152160
}
153161

154-
Widget _buildDetail(BuildContext context, DetailState state) {
155-
if (state is DetailWithData) {
156-
return Column(
157-
crossAxisAlignment: CrossAxisAlignment.start,
158-
children: [
159-
Row(
160-
children: const[
161-
Padding(
162-
padding: EdgeInsets.only(left: 15, right: 5),
163-
child: Icon(Icons.link, color: Colors.blue),
164-
),
165-
Text(
166-
'相关组件',
167-
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
168-
),
169-
],
170-
),
171-
_buildLinkTo(context, state.links),
172-
const Divider(),
173-
_buildNodes(state.nodes, state.widgetModel.name)
174-
],
175-
);
176-
}
177-
return Container();
178-
}
179-
180162
Color? get chipColor => isDark
181163
? Theme.of(context).floatingActionButtonTheme.backgroundColor
182164
: Theme.of(context).primaryColor;
@@ -196,103 +178,43 @@ class _WidgetDetailPageState extends State<WidgetDetailPage> {
196178
child: Wrap(
197179
spacing: 5,
198180
children: links
199-
.map((e) => ActionChip(
200-
onPressed: () {
201-
BlocProvider.of<WidgetDetailBloc>(context)
202-
.add(FetchWidgetDetail(e));
203-
setState(() {
204-
_modelStack.add(e);
205-
});
206-
},
181+
.map((WidgetModel model) => ActionChip(
182+
onPressed: () => _toLinkWidget(model),
207183
elevation: 2,
208184
shadowColor: chipColor,
209185
backgroundColor: chipColor,
210-
labelStyle: TextStyle(
211-
fontSize: 12,
212-
color: Colors.white,
213-
decoration: (e.deprecated)
214-
? TextDecoration.lineThrough
215-
: TextDecoration.none,
216-
decorationThickness: 2,
217-
),
218-
label: Text(e.name),
186+
labelStyle: model.deprecated
187+
? TStyleUnit.deprecatedChip
188+
: TStyleUnit.commonChip,
189+
label: Text(model.name),
219190
))
220191
.toList(),
221192
),
222193
);
223194
}
224195
}
225-
}
226-
227-
class WidgetDetailTitle extends StatelessWidget {
228-
final WidgetModel model;
229196

230-
const WidgetDetailTitle({Key? key, required this.model}) : super(key: key);
231-
232-
@override
233-
Widget build(BuildContext context) {
234-
return Column(
235-
crossAxisAlignment: CrossAxisAlignment.start,
236-
children: <Widget>[
237-
Row(
238-
children: <Widget>[
239-
_buildLeft(model, context),
240-
_buildRight(model),
241-
],
242-
),
243-
const Divider(),
244-
],
245-
);
197+
void _toLinkWidget(WidgetModel model) {
198+
BlocProvider.of<WidgetDetailBloc>(context).add(FetchWidgetDetail(model));
199+
_modelStack.add(model);
246200
}
247201

248-
Widget _buildLeft(WidgetModel model, BuildContext context) => Expanded(
249-
child: Column(
250-
crossAxisAlignment: CrossAxisAlignment.start,
251-
children: <Widget>[
252-
Padding(
253-
padding: const EdgeInsets.only(top: 20.0, left: 20),
254-
child: Text(
255-
model.nameCN,
256-
style: TextStyle(
257-
fontSize: 20,
258-
decoration: (model.deprecated)
259-
? TextDecoration.lineThrough
260-
: TextDecoration.none,
261-
decorationThickness: 2,
262-
color: const Color(0xff1EBBFD),
263-
fontWeight: FontWeight.bold),
264-
),
265-
),
266-
Padding(
267-
padding: const EdgeInsets.all(8.0),
268-
child: Panel(
269-
color: Theme.of(context).appBarTheme.backgroundColor,
270-
child: Text(model.info)),
271-
)
272-
],
273-
),
274-
);
275-
276-
Widget _buildRight(WidgetModel model) => Column(
277-
mainAxisSize: MainAxisSize.min,
278-
children: <Widget>[
279-
SizedBox(
280-
height: 100,
281-
child: Padding(
282-
padding: const EdgeInsets.all(8.0),
283-
child: Hero(
284-
tag: "hero_widget_image_${model.id}",
285-
child: ClipRRect(
286-
borderRadius: const BorderRadius.all(Radius.circular(8)),
287-
child: model.image == null
288-
? Image.asset('assets/images/caver.webp')
289-
: Image(image: model.image!))),
290-
),
291-
),
292-
StarScore(
293-
score: model.lever,
294-
star: const Star(size: 15, fillColor: Colors.blue),
295-
)
296-
],
297-
);
202+
Widget _buildSliverNodeList(List<NodeModel> nodes, String name) {
203+
GlobalState globalState = BlocProvider.of<GlobalBloc>(context).state;
204+
HighlighterStyle codeStyle =
205+
Cons.codeThemeSupport.keys.toList()[globalState.codeStyleIndex];
206+
return SliverList(
207+
delegate: SliverChildBuilderDelegate(
208+
(_, i) => WidgetNodePanel(
209+
codeStyle: codeStyle,
210+
codeFamily: 'Inconsolata',
211+
text: nodes[i].name,
212+
subText: nodes[i].subtitle,
213+
code: nodes[i].code,
214+
show: WidgetsMap.map(name)[i],
215+
),
216+
childCount: nodes.length,
217+
));
218+
}
298219
}
220+

0 commit comments

Comments
 (0)