Skip to content

Commit 6c3782c

Browse files
committed
nav transition
1 parent 33fcf39 commit 6c3782c

File tree

8 files changed

+302
-46
lines changed

8 files changed

+302
-46
lines changed

fonts/Pacifico-Regular.ttf

-197 KB
Binary file not shown.

lib/components/card.dart

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'package:Tunein/models/playerstate.dart';
88

99
class MyCard extends StatelessWidget {
1010
final Song _song;
11-
String _duration;
1211
final musicService = locator<MusicService>();
1312

1413
MyCard({Key key, @required Song song})
@@ -17,7 +16,6 @@ class MyCard extends StatelessWidget {
1716

1817
@override
1918
Widget build(BuildContext context) {
20-
parseDuration();
2119
return StreamBuilder(
2220
stream: musicService.playerState$,
2321
builder: (BuildContext context,
@@ -41,14 +39,19 @@ class MyCard extends StatelessWidget {
4139
children: <Widget>[
4240
Padding(
4341
padding: EdgeInsets.only(right: 15),
44-
child: FadeInImage(
45-
placeholder: AssetImage('images/track.png'),
46-
fadeInDuration: Duration(milliseconds: 100),
47-
image: _song.albumArt != null
48-
? FileImage(
49-
new File(_song.albumArt),
50-
)
51-
: AssetImage('images/track.png'),
42+
child: SizedBox(
43+
height: 62,
44+
width: 62,
45+
child: FadeInImage(
46+
placeholder: AssetImage('images/track.png'),
47+
fadeInDuration: Duration(milliseconds: 200),
48+
fadeOutDuration: Duration(milliseconds: 100),
49+
image: _song.albumArt != null
50+
? FileImage(
51+
new File(_song.albumArt),
52+
)
53+
: AssetImage('images/track.png'),
54+
),
5255
),
5356
),
5457
Flexible(
@@ -84,31 +87,19 @@ class MyCard extends StatelessWidget {
8487
),
8588
),
8689
Padding(
87-
padding: const EdgeInsets.only(right: 10.0),
88-
child: Text(
89-
_duration,
90-
style: TextStyle(
91-
color: Colors.white70,
92-
fontWeight: FontWeight.w600,
93-
fontSize: 12,
94-
),
95-
),
96-
),
90+
padding: const EdgeInsets.only(right: 10.0),
91+
child: IconButton(
92+
icon: Icon(
93+
IconData(0xea7c, fontFamily: 'boxicons'),
94+
size: 22,
95+
),
96+
onPressed: () {},
97+
color: Colors.white30,
98+
)),
9799
],
98100
),
99101
);
100102
},
101103
);
102104
}
103-
104-
void parseDuration() {
105-
final double _temp = _song.duration / 1000;
106-
final int _minutes = (_temp / 60).floor();
107-
final int _seconds = (((_temp / 60) - _minutes) * 60).round();
108-
if (_seconds.toString().length != 1) {
109-
_duration = _minutes.toString() + ":" + _seconds.toString();
110-
} else {
111-
_duration = _minutes.toString() + ":0" + _seconds.toString();
112-
}
113-
}
114105
}

lib/pages/home.dart

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:Tunein/services/musicService.dart';
77
import 'package:flute_music_player/flute_music_player.dart';
88
import 'package:flutter/material.dart';
99
import 'package:flutter/rendering.dart';
10+
import 'dart:math' as math;
1011

1112

1213
class HomePage extends StatefulWidget {
@@ -34,8 +35,6 @@ class HomePageState extends State<HomePage> {
3435
color: MyTheme.darkBlack,
3536
child: Column(
3637
children: <Widget>[
37-
PageHeader("Library", "All Tracks",
38-
MapEntry(IconData(0xeccd, fontFamily: 'boxicons'), Colors.white)),
3938
Expanded(
4039
child: StreamBuilder(
4140
stream: musicService.songs$,
@@ -52,6 +51,7 @@ class HomePageState extends State<HomePage> {
5251
return ListView.builder(
5352
shrinkWrap: true,
5453
itemExtent: 62,
54+
// physics: CustomScrollPhysics(),
5555
physics: AlwaysScrollableScrollPhysics(),
5656
itemCount: _songs.length,
5757
itemBuilder: (context, index) {
@@ -66,8 +66,10 @@ class HomePageState extends State<HomePage> {
6666
final Song _currentSong = snapshot.data.value;
6767
final bool _isSelectedSong =
6868
_currentSong == _songs[index];
69-
return GestureDetector(
69+
return InkWell(
70+
enableFeedback: false,
7071
onTap: () {
72+
print("Wtf");
7173
musicService.updatePlaylist(_songs);
7274
switch (_state) {
7375
case PlayerState.playing:
@@ -114,3 +116,60 @@ class HomePageState extends State<HomePage> {
114116
);
115117
}
116118
}
119+
120+
class CustomSimulation extends Simulation {
121+
final double initPosition;
122+
final double velocity;
123+
final double maxPos;
124+
125+
CustomSimulation({this.initPosition,this.maxPos,this.velocity});
126+
127+
@override
128+
double x(double time) {
129+
var max =
130+
math.max(math.min(initPosition, 0.0), math.min(initPosition + velocity * time, maxPos));
131+
132+
// print(max.toString());
133+
134+
return max;
135+
}
136+
137+
@override
138+
double dx(double time) {
139+
// print(velocity.toString());
140+
return velocity;
141+
}
142+
143+
@override
144+
bool isDone(double time) {
145+
return false;
146+
}
147+
}
148+
149+
class CustomScrollPhysics extends ScrollPhysics {
150+
151+
const CustomScrollPhysics({ ScrollPhysics parent }) : super(parent: parent);
152+
153+
@override
154+
CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
155+
return CustomScrollPhysics(parent: buildParent(ancestor));
156+
}
157+
158+
// @override
159+
// ScrollPhysics applyTo(ScrollPhysics ancestor) {
160+
// return CustomScrollPhysics();
161+
// }
162+
163+
@override
164+
bool shouldAcceptUserOffset(ScrollMetrics position) => true;
165+
166+
@override
167+
Simulation createBallisticSimulation(
168+
ScrollMetrics position, double velocity) {
169+
return CustomSimulation(
170+
initPosition: position.pixels,
171+
maxPos:position.maxScrollExtent,
172+
velocity: velocity,
173+
);
174+
}
175+
}

lib/root.dart

Lines changed: 142 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import 'dart:async';
22

3+
import 'package:Tunein/components/appbar.dart';
34
import 'package:Tunein/pages/favorites.dart';
45
import 'package:Tunein/pages/home.dart';
6+
import 'package:Tunein/services/layout.dart';
57
import 'package:Tunein/services/locator.dart';
68
import 'package:Tunein/services/musicService.dart';
79
import 'package:flutter/material.dart';
810
import 'package:Tunein/components/playing.dart';
911
import 'package:flutter/services.dart';
1012
import 'package:sliding_up_panel/sliding_up_panel.dart';
11-
import 'components/appbar.dart';
1213
import 'components/bottomPanel.dart';
1314
import 'globals.dart';
15+
import 'dart:math' as math;
1416

1517
enum StartupState { Busy, Success, Error }
1618

@@ -20,18 +22,44 @@ class Root extends StatefulWidget {
2022

2123
class RootState extends State<Root> with TickerProviderStateMixin {
2224
final musicService = locator<MusicService>();
25+
final layoutService = locator<LayoutService>();
2326

2427
PanelController _panelController;
2528
PageController _pageController;
29+
ScrollController _headerController;
30+
double offset;
31+
double width;
32+
33+
List<double> navSizes = [];
34+
2635
final StreamController<StartupState> _startupStatus =
2736
StreamController<StartupState>();
2837
final _androidAppRetain = MethodChannel("android_app_retain");
2938
@override
3039
void initState() {
3140
_panelController = PanelController();
3241
_pageController = PageController();
42+
_headerController = ScrollController();
43+
offset = 0;
44+
width = 0;
45+
3346
_startupStatus.add(StartupState.Busy);
3447
loadFiles();
48+
49+
_pageController.addListener(() {
50+
int round = (_pageController.page).round();
51+
int floor = (_pageController.page).floor();
52+
53+
layoutService.updatePageIndex(_pageController.page);
54+
55+
offset = layoutService.cumulativeNavSizes[floor];
56+
57+
width = layoutService.navSizes[floor];
58+
59+
_headerController
60+
.jumpTo((_pageController.page - floor).abs() * width + offset);
61+
});
62+
3563
super.initState();
3664
}
3765

@@ -70,6 +98,7 @@ class RootState extends State<Root> with TickerProviderStateMixin {
7098
},
7199
child: Scaffold(
72100
appBar: MyAppBar(0),
101+
drawer: Drawer(),
73102
backgroundColor: MyTheme.darkBlack,
74103
body: StreamBuilder<StartupState>(
75104
stream: _startupStatus.stream,
@@ -96,10 +125,59 @@ class RootState extends State<Root> with TickerProviderStateMixin {
96125
collapsed: BottomPanel(),
97126
body: Theme(
98127
data: Theme.of(context).copyWith(accentColor: MyTheme.darkRed),
99-
child: PageView(
100-
physics: AlwaysScrollableScrollPhysics(),
101-
controller: _pageController,
102-
children: <Widget>[HomePage(), FavoritesPage()],
128+
child: Column(
129+
children: <Widget>[
130+
Container(
131+
height: 60,
132+
// padding: EdgeInsets.only(left: 20),
133+
child: Row(
134+
children: <Widget>[
135+
Padding(
136+
padding:
137+
const EdgeInsets.symmetric(horizontal: 10),
138+
child: IconButton(
139+
onPressed: () {},
140+
icon: Icon(
141+
IconData(0xeaea, fontFamily: 'boxicons'),
142+
size: 30,
143+
color: Colors.white,
144+
),
145+
)),
146+
Expanded(
147+
child: ListView.builder(
148+
controller: _headerController,
149+
scrollDirection: Axis.horizontal,
150+
itemCount:
151+
layoutService.mainNavitems.length + 1,
152+
itemBuilder: (context, int index) {
153+
var items = layoutService.mainNavitems;
154+
if (index ==
155+
layoutService.mainNavitems.length) {
156+
return Container(
157+
width: 1000,
158+
);
159+
}
160+
return PageTitle(
161+
index: index,
162+
key: items[index].value,
163+
title: items[index].key.toUpperCase(),
164+
);
165+
},
166+
),
167+
)
168+
],
169+
)),
170+
Expanded(
171+
child: PageView(
172+
physics: AlwaysScrollableScrollPhysics(),
173+
controller: _pageController,
174+
children: <Widget>[
175+
HomePage(),
176+
FavoritesPage(),
177+
],
178+
),
179+
)
180+
],
103181
),
104182
),
105183
);
@@ -109,3 +187,62 @@ class RootState extends State<Root> with TickerProviderStateMixin {
109187
);
110188
}
111189
}
190+
191+
class PageTitle extends StatelessWidget {
192+
final layoutService = locator<LayoutService>();
193+
final String title;
194+
final int index;
195+
PageTitle({
196+
Key key,
197+
this.title,
198+
this.index,
199+
}) : super(key: key);
200+
201+
onAfterBuild(context) {
202+
layoutService.setSize(index);
203+
}
204+
205+
@override
206+
Widget build(BuildContext context) {
207+
return StreamBuilder<double>(
208+
stream: layoutService.pageIndex$.stream,
209+
builder: (context, AsyncSnapshot<double> snapshot) {
210+
if (!snapshot.hasData) {
211+
return Container();
212+
}
213+
final double pageValue = snapshot.data;
214+
215+
double opacity = 0.24;
216+
int floor = pageValue.floor();
217+
int ceil = pageValue.ceil();
218+
219+
if (index == ceil && index == floor) {
220+
opacity = 1;
221+
} else {
222+
double dx = (ceil - pageValue);
223+
224+
if (index == floor) {
225+
opacity = math.max(dx, 0.24);
226+
}
227+
if (index == ceil) {
228+
opacity = math.max(1 - dx, 0.24);
229+
}
230+
}
231+
232+
WidgetsBinding.instance
233+
.addPostFrameCallback((_) => onAfterBuild(context));
234+
return Container(
235+
// width: 116,
236+
alignment: Alignment.centerLeft,
237+
child: Text(
238+
title,
239+
style: TextStyle(
240+
color: Colors.white.withOpacity(opacity),
241+
fontSize: 22,
242+
fontWeight: FontWeight.bold,
243+
),
244+
),
245+
);
246+
});
247+
}
248+
}

0 commit comments

Comments
 (0)