Skip to content

Commit af9a2b3

Browse files
committed
Add: Wave styles widget
1 parent 1245fcd commit af9a2b3

File tree

8 files changed

+338
-1
lines changed

8 files changed

+338
-1
lines changed

lib/component/main/MainPage.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class _MainState extends State<MainPage> {
6464
"Segment",
6565
"DropDown",
6666
"Popup",
67+
"Wave",
6768
];
6869
return _sortTitles;
6970
}
@@ -88,6 +89,7 @@ class _MainState extends State<MainPage> {
8889
"/SegmentPage",
8990
"/DropDownPage",
9091
"/MainPopupPage",
92+
"/MainWavePage",
9193
];
9294
return _sortRouteNames;
9395
}

lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import 'package:flutter_app_sample/sample/ink/ink_page.dart';
2424
import 'package:flutter_app_sample/sample/notifier/CardInfoPage.dart';
2525
import 'package:flutter_app_sample/sample/notifier/CardMainPage.dart';
2626
import 'package:flutter_app_sample/sample/popup/main_popup_page.dart';
27+
import 'package:flutter_app_sample/sample/wave/main_wave_page.dart';
2728
import 'package:flutter_localizations/flutter_localizations.dart';
2829
import 'package:provider/provider.dart';
2930

@@ -122,6 +123,7 @@ class Test extends StatelessWidget {
122123
"/SegmentPage": (_) => SegmentPage(),
123124
"/DropDownPage": (_) => DropDownPage(),
124125
"/MainPopupPage": (_) => MainPopupPage(),
126+
"/MainWavePage": (_) => MainWavePage(),
125127
},
126128
);
127129
},

lib/sample/popup/main_popup_page.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class _MainPopupState extends State<MainPopupPage> {
4343
label: Text("left top"),
4444
),
4545
Spacer(),
46+
Spacer(),
4647
RaisedButton.icon(
4748
key: btnKey2,
4849
onPressed: () {
@@ -52,6 +53,7 @@ class _MainPopupState extends State<MainPopupPage> {
5253
label: Text("left center"),
5354
),
5455
Spacer(),
56+
Spacer(),
5557
RaisedButton.icon(
5658
key: btnKey3,
5759
onPressed: () {
@@ -75,6 +77,7 @@ class _MainPopupState extends State<MainPopupPage> {
7577
label: Text("right top"),
7678
),
7779
Spacer(),
80+
Spacer(),
7881
RaisedButton.icon(
7982
key: btnKey2Right,
8083
onPressed: () {
@@ -84,6 +87,7 @@ class _MainPopupState extends State<MainPopupPage> {
8487
label: Text("right center"),
8588
),
8689
Spacer(),
90+
Spacer(),
8791
RaisedButton.icon(
8892
key: btnKey3Right,
8993
onPressed: () {

lib/sample/progress/main_progress_page.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class _MainProgressState extends State<MainProgressPage>
7777
valueColor: _colorTween,
7878
),
7979
),
80-
Text("$_slideValue/%"),
80+
Text("$_slideValue%"),
8181
],
8282
),
8383
Slider(
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import 'dart:ui';
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_app_sample/sample/wave/wave_triangle_clipper.dart';
5+
6+
import 'wave_arc_clipper.dart';
7+
import 'wave_oval_clipper.dart';
8+
9+
class MainWavePage extends StatefulWidget {
10+
@override
11+
State<StatefulWidget> createState() {
12+
return _MainWaveState();
13+
}
14+
}
15+
16+
class _MainWaveState extends State<MainWavePage> {
17+
static const double min = 2;
18+
static const double max = 30;
19+
double _slideValue = min + 1;
20+
int _slideDivisions = (max - min).toInt();
21+
int _waveCount = 1;
22+
23+
@override
24+
Widget build(BuildContext context) {
25+
return Scaffold(
26+
appBar: AppBar(
27+
title: Text("Wave"),
28+
),
29+
body: Column(
30+
children: <Widget>[
31+
Spacer(),
32+
Spacer(),
33+
Slider(
34+
value: _slideValue,
35+
min: min,
36+
max: max,
37+
divisions: _slideDivisions,
38+
label: "$_waveCount",
39+
onChanged: (double value) {
40+
setState(() {
41+
_slideValue = value;
42+
_waveCount = value.toInt();
43+
});
44+
},
45+
),
46+
Divider(),
47+
Spacer(),
48+
Container(
49+
width: MediaQuery.of(context).size.width,
50+
height: 50,
51+
child: ClipPath(
52+
key: GlobalKey(),
53+
clipBehavior: Clip.antiAlias,
54+
clipper:
55+
WaveTriangleClipper(waveCount: _waveCount, isReverse: false),
56+
child: BlueGradient(),
57+
),
58+
),
59+
Divider(),
60+
Spacer(),
61+
Container(
62+
width: MediaQuery.of(context).size.width,
63+
height: 50,
64+
child: ClipPath(
65+
key: GlobalKey(),
66+
clipBehavior: Clip.antiAlias,
67+
clipper: WaveOvalClipper(waveCount: _waveCount, isReverse: false),
68+
child: BlueGradient(),
69+
),
70+
),
71+
Divider(),
72+
Spacer(),
73+
Container(
74+
width: MediaQuery.of(context).size.width,
75+
height: 50,
76+
child: ClipPath(
77+
key: GlobalKey(),
78+
clipBehavior: Clip.antiAlias,
79+
clipper: WaveArcClipper(waveCount: _waveCount, isReverse: false),
80+
child: BlueGradient(),
81+
),
82+
),
83+
Divider(),
84+
Spacer(),
85+
Spacer(),
86+
],
87+
),
88+
);
89+
}
90+
}
91+
92+
class BlueGradient extends StatelessWidget {
93+
final overlayHeight = 50.0;
94+
95+
@override
96+
Widget build(BuildContext context) {
97+
return Container(
98+
height: overlayHeight,
99+
decoration: BoxDecoration(
100+
gradient: LinearGradient(
101+
begin: FractionalOffset.topCenter,
102+
end: FractionalOffset.bottomCenter,
103+
colors: [
104+
Colors.blue,
105+
Colors.blue.withOpacity(0.25),
106+
],
107+
),
108+
),
109+
);
110+
}
111+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import 'package:flutter/material.dart';
2+
3+
/// WaveArcClipper
4+
///
5+
/// 圆弧效果的
6+
class WaveArcClipper extends CustomClipper<Path> {
7+
int _count;
8+
bool _isReverse;
9+
10+
WaveArcClipper({
11+
int waveCount,
12+
bool isReverse = false,
13+
}) {
14+
_count = waveCount;
15+
_isReverse = isReverse;
16+
}
17+
18+
@override
19+
Path getClip(Size size) {
20+
var path = Path();
21+
22+
var _segment = _count * 2;
23+
24+
double pieceOfWidth = size.width / _segment;
25+
double pieceOfHeight = size.height;
26+
27+
if (_isReverse) {
28+
path.moveTo(0, 0);
29+
} else {
30+
path.moveTo(0, pieceOfHeight);
31+
}
32+
33+
for (int i = 0; i < _segment; i++) {
34+
double y = 0.0;
35+
36+
double left;
37+
double top;
38+
double right;
39+
double bottom;
40+
41+
double startAngle;
42+
double sweepAngle;
43+
44+
if (_isReverse) {
45+
if (i % 2 == 1) {
46+
y = 0;
47+
left = pieceOfWidth * i;
48+
top = y;
49+
} else {
50+
y = pieceOfHeight;
51+
left = pieceOfWidth * i;
52+
top = y;
53+
}
54+
} else {
55+
if (i % 2 == 1) {
56+
y = pieceOfHeight;
57+
left = pieceOfWidth * i;
58+
top = y;
59+
startAngle = 180;
60+
sweepAngle = -45;
61+
} else {
62+
y = 0;
63+
left = pieceOfWidth * i;
64+
top = y;
65+
startAngle = 180;
66+
sweepAngle = 45;
67+
}
68+
}
69+
Rect rect =
70+
Rect.fromLTRB(left, top, left + pieceOfWidth, top + pieceOfHeight);
71+
path.arcTo(rect, startAngle, sweepAngle, false);
72+
}
73+
74+
path.close();
75+
return path;
76+
}
77+
78+
@override
79+
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
80+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import 'package:flutter/material.dart';
2+
3+
/// WaveOvalClipper
4+
///
5+
/// 椭圆效果的
6+
class WaveOvalClipper extends CustomClipper<Path> {
7+
int _count;
8+
bool _isReverse;
9+
10+
WaveOvalClipper({
11+
int waveCount,
12+
bool isReverse = false,
13+
}) {
14+
_count = waveCount;
15+
_isReverse = isReverse;
16+
}
17+
18+
@override
19+
Path getClip(Size size) {
20+
var path = Path();
21+
22+
var _segment = _count * 2;
23+
24+
double pieceOfWidth = size.width / _segment;
25+
double pieceOfHeight = size.height;
26+
27+
if (_isReverse) {
28+
path.moveTo(0, 0);
29+
} else {
30+
path.moveTo(0, pieceOfHeight);
31+
}
32+
33+
for (int i = 0; i < _segment; i++) {
34+
double y = 0.0;
35+
36+
double left;
37+
double top;
38+
double right;
39+
double bottom;
40+
41+
double startAngle;
42+
double sweepAngle;
43+
44+
if (_isReverse) {
45+
if (i % 2 == 1) {
46+
y = 0;
47+
left = pieceOfWidth * i;
48+
top = y;
49+
} else {
50+
y = pieceOfHeight;
51+
left = pieceOfWidth * i;
52+
top = y;
53+
}
54+
} else {
55+
if (i % 2 == 1) {
56+
y = pieceOfHeight;
57+
left = pieceOfWidth * i;
58+
top = y;
59+
startAngle = 180;
60+
sweepAngle = -45;
61+
} else {
62+
y = 0;
63+
left = pieceOfWidth * i;
64+
top = y;
65+
startAngle = 180;
66+
sweepAngle = 45;
67+
}
68+
}
69+
Rect rect =
70+
Rect.fromLTRB(left, top, left + pieceOfWidth, top + pieceOfHeight);
71+
path.addOval(rect);
72+
}
73+
74+
path.close();
75+
return path;
76+
}
77+
78+
@override
79+
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
80+
}

0 commit comments

Comments
 (0)