Skip to content

Commit

Permalink
播放器效果
Browse files Browse the repository at this point in the history
  • Loading branch information
Dao-Ke committed Jan 15, 2023
1 parent 43f8102 commit 0bacd20
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 58 deletions.
25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "learn_flutter",
"request": "launch",
"type": "dart"
},
{
"name": "learn_flutter (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "learn_flutter (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}
Binary file added images/01.webp
Binary file not shown.
212 changes: 212 additions & 0 deletions lib/list/audioplayer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:learn_flutter/common/commons.dart';
import 'package:logger/logger.dart';

final logger = Logger();

class AudioPlayerRoute extends StatefulWidget {
const AudioPlayerRoute({super.key});

@override
State<AudioPlayerRoute> createState() => _AudioPlayerRouteState();
}

class _AudioPlayerRouteState extends State<AudioPlayerRoute>
with TickerProviderStateMixin {
late AnimationController _coverController;
late AnimationController _progressController;

@override
void initState() {
super.initState();
_coverController = AnimationController(
duration: const Duration(seconds: 6),
vsync: this,
)..repeat(reverse: false);
_progressController =
AnimationController(vsync: this, duration: const Duration(seconds: 201))
..addListener(() {
setState(() {});
})
..forward();
}

@override
void dispose() {
_coverController.dispose();
_progressController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
var rotateImage = RotationTransition(
turns: _coverController,
child: Image.asset(
"images/01.webp",
fit: BoxFit.cover,
),
);
return MaterialApp(
theme: ThemeData(
colorSchemeSeed: const Color(0xff6750a4),
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("AudioPlayer"),
leading: const IconButton(
onPressed: null,
icon: Icon(
Icons.arrow_back_ios,
color: Colors.black,
),
),
actions: const [
_MyMenuAction(),
],
),
body: Column(
children: [
const Spacer(flex: 1),
Center(child: _buildAudioCoverWidget(rotateImage)),
const Spacer(),
const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text(
"Draft Punk",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
color: Colors.black87),
),
),
),
const Center(
child: Text(
"instant crush",
style: TextStyle(fontSize: 16, color: Colors.black54),
),
),
const Spacer(flex: 2),
Row(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
"0:00",
style: TextStyle(fontSize: 16, color: Colors.black45),
),
),
Flexible(
child: LinearProgressIndicator(
value: _progressController.value,
),
),
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
"3:21",
style: TextStyle(fontSize: 16, color: Colors.black45),
),
),
],
),
const Spacer(flex: 3),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.fast_rewind,
size: 48,
color: Colors.black45,
),
Padding(
padding: EdgeInsets.all(16.0),
child: Icon(
Icons.pause,
size: 72,
color: Colors.black54,
),
),
Icon(
Icons.fast_forward,
size: 48,
color: Colors.black45,
)
],
),
const Spacer(flex: 2),
],
),
),
);
}

Widget _buildAudioCoverWidget(Widget image) {
var ring = SizedBox(
width: 220,
height: 220,
child: ClipPath(
clipper: _MyPathClipper(),
child: image,
),
);
return Stack(
alignment: AlignmentDirectional.center,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(60, 60, 20, 20),
child: ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: 10, sigmaY: 10, tileMode: TileMode.decal),
child: ring,
),
),
ring,
],
);
}
}

class _MyPathClipper extends CustomClipper<Path> {
static const double hollowRatio = 1 / 4;
@override
Path getClip(Size size) {
var path = Path();
path.addOval(Rect.fromCenter(
center: Offset(size.width / 2, size.height / 2),
width: size.width * hollowRatio,
height: size.height * hollowRatio));
path.addOval(Offset.zero & size);
path.fillType = PathFillType.evenOdd;
return path;
}

@override
bool shouldReclip(covariant CustomClipper oldClipper) {
return false;
}
}

class _MyMenuAction extends StatelessWidget {
const _MyMenuAction({super.key});

@override
Widget build(BuildContext context) {
return SizedBox.square(
dimension: 56,
child: IconButton(
icon: const Icon(Icons.menu),
onPressed: () {
logger.d("menu clicked");
showShackBar(context, "menu clicked");
},
),
);
}
}
56 changes: 0 additions & 56 deletions lib/list/mediaplayer.dart

This file was deleted.

2 changes: 1 addition & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:learn_flutter/list/learn_list.dart';
import 'package:learn_flutter/list/learn_animated_list.dart';
import 'package:learn_flutter/list/mediaplayer.dart';
import 'package:learn_flutter/list/audioplayer.dart';

void main() {
runApp(MyApp(items: _buildMainRouteList()));
Expand Down
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ flutter:

# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages

assets:
- images/
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
Expand Down

0 comments on commit 0bacd20

Please sign in to comment.