猫哥说

这是个自动管理响应界面处理的组件,比较适合在 flutter web 的项目中。

自动管理了你的 Resizing、最大、最小尺寸、Scaling 缩放比例,但是我没有发现布局的控制,但是这已经很不错了,又可以少写代码了。

  • 最小尺寸效果

https://gallery.codelessly.com/flutterwebsites/minimal/?utm_medium=link&utm_campaign=demo#/

  • Flutter.dev 官网

https://gallery.codelessly.com/flutterwebsites/flutterwebsite/?utm_medium=link&utm_campaign=demo

老铁记得 转发 ,猫哥会呈现更多 Flutter 好文~~~~

微信群 ducafecat

b 站 https://space.bilibili.com/404904528

原文

https://medium.com/flutterdevs/responsive-framework-in-flutter-74b8b2a360a9

代码

https://github.com/ducafecat/getx_quick_start

参考

正文

Flutter 是 Google 的用户界面工具宝库,用于从一个代码库生成优秀的、本地编译的 iOS 和 Android 应用程序。为了构建任何应用程序,我们从小部件开始ー Flutter 应用程序的构建方块。窗口小部件根据当前的设计和状态描述他们的视图应该类似的内容。它整合了一个文本小部件、行小部件、列小部件、容器小部件等等。

本文利用 Flutter 响应框架软件包对 Flutter 响应框架进行了研究。有了软件包的帮助,我们可以很容易地实现一个响应屏幕。那么让我们开始吧。

响应式框架

响应式框架会自动调整你的用户界面以适应不同的屏幕尺寸。创建您的用户界面一次,并有它显示像素完美的移动,平板电脑和桌面!

支持多种显示大小通常意味着多次重新创建相同的布局。在传统的 Bootstrap 方法下,构建响应式 UI 是耗时、令人沮丧和重复的。此外,让一切像素完美几乎是不可能的,简单的编辑需要几个小时。

实施方案

  • 第一步: 添加依赖项

将依赖项添加到 pubspec.yaml 文件。

依赖性:

1
2
dependencies:
responsive_framework: ^0.1.4
  • 第二步: 导入
1
import 'package:responsive_framework/responsive_framework.dart';
  • 第三步: 启用 AndriodX
1
2
3
4
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

代码实现

你需要分别在你的代码中实现它

在创建类似于响应式框架的 UI 之前,我们在 main 的 Material 应用部件中添加了 ResponsiveWrapper.builder() 。文件中初始化 MaxWith,MinWith 和 Breakpoints 的 List 类型,在它内部调整设备的大小,如移动设备,平板电脑,桌面,并且自动缩放值是定义的,让我们理解它与下面的代码引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ResponsiveWrapper.builder(
BouncingScrollWrapper.builder(context, widget!),
maxWidth: 1200,
minWidth: 450,
defaultScale: true,
breakpoints: [
ResponsiveBreakpoint.resize(450, name: MOBILE),
ResponsiveBreakpoint.autoScale(800, name: MOBILE),
ResponsiveBreakpoint.autoScale(800, name: TABLET),
ResponsiveBreakpoint.autoScale(1000, name: TABLET),
ResponsiveBreakpoint.resize(1200, name: DESKTOP),
ResponsiveBreakpoint.autoScale(2460, name: "4K"),
],
background: Container(color: Color(0xFFF5F5F5))
),

自动缩放按比例缩小和扩展布局,保持 UI 的精确外观。这就消除了手动调整布局以适应移动设备、平板电脑和桌面的需要。

在此之后,我们创建了一个用户配置文件屏幕,其中是用户的图像,以及两种不同类型的列表,其中图像和一些文本已经给出。

全部代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
import 'package:flutter/material.dart';
import 'package:responsive_framwork_demo/Constants/Constants.dart';
import 'package:responsive_framwork_demo/device_size.dart';
import 'package:responsive_framwork_demo/model/popular_course_model.dart';
import 'package:responsive_framwork_demo/model/result_model.dart';

class ProfileScreen extends StatefulWidget {
@override
_ProfileScreenState createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
late List<PopularCourseModel> popularCourseModel;
late List<ResultModel> resultModel;

@override
void initState() {
popularCourseModel = Constants.getPopularCourseModel();
resultModel = Constants.getResultModel();

super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0.0,
title: Text(
'PROFILE',
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.bold,
letterSpacing: 0.5),
),
centerTitle: true,
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(top: 20),
child: Column(
children: [
ClipOval(
child: CircleAvatar(
maxRadius: 50,
child: Image.asset(
'assets/images/mans_img.jpeg',
width: DeviceSize.width(context),
fit: BoxFit.fill,
),
),
),
SizedBox(
height: 30,
),
Text(
'Crowley Singer',
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.bold,
letterSpacing: 0.3),
),
Container(
margin: EdgeInsets.only(top: 25, left: 20, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(
'22',
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.bold,
letterSpacing: 0.5),
),
SizedBox(
height: 10,
),
Text(
'Courses',
style: TextStyle(
fontFamily: 'Poppins Regular',
color: Colors.black45,
fontSize: 11,
fontWeight: FontWeight.bold,
letterSpacing: 0.3),
),
],
),
Container(
height: 32,
width: 1,
color: Colors.black12,
),
Column(
children: [
Text(
'32',
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.bold,
letterSpacing: 0.5),
),
SizedBox(
height: 10,
),
Text(
'Mentors',
style: TextStyle(
fontFamily: 'Poppins Regular',
color: Colors.black45,
fontSize: 11,
fontWeight: FontWeight.bold,
letterSpacing: 0.3),
),
],
),
Container(
height: 32,
width: 1,
color: Colors.black12,
),
Column(
children: [
Text(
'48',
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.bold,
letterSpacing: 0.5),
),
SizedBox(
height: 10,
),
Text(
'Friends',
style: TextStyle(
fontFamily: 'Poppins Regular',
color: Colors.black45,
fontSize: 11,
fontWeight: FontWeight.bold,
letterSpacing: 0.3),
),
],
),
],
),
),
Container(
margin: EdgeInsets.only(top: 30, left: 20, right: 20),
height: 1,
color: Colors.black12,
width: DeviceSize.width(context),
),
Container(
margin: EdgeInsets.only(top: 30, left: 20, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'YOUR COURSES',
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 12,
fontWeight: FontWeight.w700,
letterSpacing: 0.5),
),
Icon(Icons.more_horiz),
],
),
),
Container(
margin: EdgeInsets.only(top: 10, left: 20, right: 20),
height: DeviceSize.height(context) / 7,
// color:Colors.purple,
child: ListView.separated(
separatorBuilder: (BuildContext context, int index) {
return SizedBox(width: 10);
},
scrollDirection: Axis.horizontal,
// padding:EdgeInsets.only(left:10),
//shrinkWrap: true,
itemCount: popularCourseModel.length,
itemBuilder: (BuildContext context, int index) {
return _buildYourCourseModel(
popularCourseModel[index], index);
},
),
),
Container(
margin: EdgeInsets.only(top: 30, left: 20, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'YOUR PROGRESS',
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 12,
fontWeight: FontWeight.w700,
letterSpacing: 0.5),
),
Icon(Icons.more_horiz),
],
),
),
Container(
// height:DeviceSize.height(context),
width: DeviceSize.width(context),

margin: EdgeInsets.only(top: 20),

child: ListView.separated(
separatorBuilder: (BuildContext context, int index) {
return SizedBox(height: 10);
},
scrollDirection: Axis.vertical,
// padding:EdgeInsets.only(left:10),
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: resultModel.length,
itemBuilder: (BuildContext context, int index) {
return _buildResultModel(resultModel[index], index);
},
),
),
],
),
),
),
);
}

Widget _buildYourCourseModel(PopularCourseModel items, int index) {
return Container(
width: 70,
child: Column(
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.blueGrey.shade50,
offset: const Offset(
5.0,
5.0,
),
blurRadius: 10.0,
spreadRadius: 2.0,
), //BoxShadow
BoxShadow(
color: Colors.white,
offset: const Offset(0.0, 0.0),
blurRadius: 0.0,
spreadRadius: 0.0,
), //BoxShadow
],
),
child: ClipOval(
child: CircleAvatar(
backgroundColor: Colors.white,
maxRadius: 30,
// child:Image.asset('assets/images/earth.png',height:45,color:Colors.blueAccent,) ,
child: Padding(
padding: EdgeInsets.all(4),
child: Image.asset(
items.img,
fit: BoxFit.cover,
scale: 7,
),
),
),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(top: 0),
alignment: Alignment.center,
child: Text(
items.title,
style: TextStyle(
fontFamily: 'Poppins Medium',
fontWeight: FontWeight.w700,
letterSpacing: 0.3,
fontSize: 11,
color: Colors.black),
),
),
),
],
),
);
}

Widget _buildResultModel(ResultModel items, int index) {
return Container(
margin: EdgeInsets.only(left: 20, right: 20),

height: DeviceSize.height(context) / 9,

// / color:Colors.pink,
child: Row(
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.blueGrey.shade50,
offset: const Offset(
5.0,
5.0,
),
blurRadius: 10.0,
spreadRadius: 2.0,
), //BoxShadow
BoxShadow(
color: Colors.white,
offset: const Offset(0.0, 0.0),
blurRadius: 0.0,
spreadRadius: 0.0,
), //BoxShadow
],
),
child: ClipOval(
child: CircleAvatar(
backgroundColor: Colors.white,
maxRadius: 28,
// child:Image.asset('assets/images/earth.png',height:45,color:Colors.blueAccent,) ,
child: Padding(
padding: EdgeInsets.all(4),
child: Image.asset(
items.img,
fit: BoxFit.cover,
scale: 7,
),
),
),
),
),
SizedBox(
width: 20,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
items.title,
style: TextStyle(
fontFamily: 'Poppins Medium',
color: Colors.black,
fontSize: 11.5,
fontWeight: FontWeight.w700,
letterSpacing: 0.5),
),
SizedBox(
height: 5,
),
Text(
items.subTitle,
style: TextStyle(
fontFamily: 'Poppins Regular',
color: Colors.black45,
fontSize: 11,
fontWeight: FontWeight.w700,
letterSpacing: 0.5),
),
],
),
],
),
);
}
}

总结

在这篇文章中,我解释了在 Flutter 响应框架,你可以根据自己的修改和实验,这个小介绍是从我们这边的 Flutter 响应框架演示。


© 猫哥

https://ducafecat.tech/

https://github.com/ducafecat

往期

开源

GetX Quick Start

https://github.com/ducafecat/getx_quick_start

新闻客户端

https://github.com/ducafecat/flutter_learn_news

strapi 手册译文

https://getstrapi.cn

微信讨论群 ducafecat

系列集合

译文

https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/

开源项目

https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/

Dart 编程语言基础

https://space.bilibili.com/404904528/channel/detail?cid=111585

Flutter 零基础入门

https://space.bilibili.com/404904528/channel/detail?cid=123470

Flutter 实战从零开始 新闻客户端

https://space.bilibili.com/404904528/channel/detail?cid=106755

Flutter 组件开发

https://space.bilibili.com/404904528/channel/detail?cid=144262

Flutter Bloc

https://space.bilibili.com/404904528/channel/detail?cid=177519

Flutter Getx4

https://space.bilibili.com/404904528/channel/detail?cid=177514

Docker Yapi

https://space.bilibili.com/404904528/channel/detail?cid=130578