mirror of
https://github.com/Iconica-Development/flutter_media_picker.git
synced 2025-05-19 08:53:45 +02:00
feat: audio styling
This commit is contained in:
parent
64fc57a8b9
commit
660549fcf6
2 changed files with 179 additions and 106 deletions
|
@ -9,3 +9,7 @@
|
||||||
## 0.0.3
|
## 0.0.3
|
||||||
|
|
||||||
- Fixed bug where onTap was not working when header is set
|
- Fixed bug where onTap was not working when header is set
|
||||||
|
|
||||||
|
## 0.1.0
|
||||||
|
|
||||||
|
- Ability to set styling for the audio input.
|
||||||
|
|
|
@ -15,10 +15,13 @@ class MediaPickerInputAudio implements MediaPickerInput {
|
||||||
this.checkPageSettings,
|
this.checkPageSettings,
|
||||||
this.onComplete,
|
this.onComplete,
|
||||||
required this.audioService,
|
required this.audioService,
|
||||||
|
this.inputStyling,
|
||||||
});
|
});
|
||||||
|
|
||||||
final AudioService audioService;
|
final AudioService audioService;
|
||||||
|
|
||||||
|
final AudioInputStyling? inputStyling;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String label;
|
String label;
|
||||||
|
|
||||||
|
@ -38,6 +41,7 @@ class MediaPickerInputAudio implements MediaPickerInput {
|
||||||
throw Exception("No recording returned");
|
throw Exception("No recording returned");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
inputStyling: inputStyling ?? AudioInputStyling(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -66,12 +70,15 @@ class Recorder extends ConsumerStatefulWidget {
|
||||||
const Recorder({
|
const Recorder({
|
||||||
required this.onComplete,
|
required this.onComplete,
|
||||||
required this.audioService,
|
required this.audioService,
|
||||||
|
required this.inputStyling,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final void Function(MediaResult value) onComplete;
|
final void Function(MediaResult value) onComplete;
|
||||||
final AudioService audioService;
|
final AudioService audioService;
|
||||||
|
|
||||||
|
final AudioInputStyling inputStyling;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<Recorder> createState() => _RecorderState();
|
ConsumerState<Recorder> createState() => _RecorderState();
|
||||||
}
|
}
|
||||||
|
@ -87,6 +94,7 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Stack(
|
body: Stack(
|
||||||
children: [
|
children: [
|
||||||
|
widget.inputStyling.background ??
|
||||||
Container(
|
Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
gradient: RadialGradient(
|
gradient: RadialGradient(
|
||||||
|
@ -107,9 +115,8 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Spacer(
|
if (widget.inputStyling.pageContent != null)
|
||||||
flex: 5,
|
widget.inputStyling.pageContent!,
|
||||||
),
|
|
||||||
StreamBuilder(
|
StreamBuilder(
|
||||||
stream: Stream.periodic(
|
stream: Stream.periodic(
|
||||||
recording
|
recording
|
||||||
|
@ -123,7 +130,8 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
clock.getCurrentTime(),
|
clock.getCurrentTime(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: Theme.of(context).textTheme.headline5,
|
style: widget.inputStyling.timeTextStyle ??
|
||||||
|
Theme.of(context).textTheme.headline5,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -133,6 +141,10 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
widget.inputStyling.playButton?.call(
|
||||||
|
recording,
|
||||||
|
playOnTap,
|
||||||
|
) ??
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 82,
|
width: 82,
|
||||||
height: 82,
|
height: 82,
|
||||||
|
@ -141,7 +153,8 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(45),
|
borderRadius:
|
||||||
|
BorderRadius.circular(45),
|
||||||
gradient: const LinearGradient(
|
gradient: const LinearGradient(
|
||||||
colors: [
|
colors: [
|
||||||
Color(0xFFF0F0F0),
|
Color(0xFFF0F0F0),
|
||||||
|
@ -176,24 +189,8 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
iconSize: 65,
|
iconSize: 65,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
splashRadius: 30,
|
splashRadius: 30,
|
||||||
onPressed: () async {
|
onPressed: () {
|
||||||
if (recording) {
|
playOnTap();
|
||||||
widget.audioService.recordStop();
|
|
||||||
|
|
||||||
clock.stopClock();
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
recording = false;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
widget.audioService.recordStart();
|
|
||||||
|
|
||||||
clock.startClock();
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
recording = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
recording
|
recording
|
||||||
|
@ -206,34 +203,37 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
widget.inputStyling.nextButton != null
|
||||||
|
? Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: widget.inputStyling.nextButton!.call(
|
||||||
|
recording,
|
||||||
|
nextOnTap,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Expanded(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
widget.audioService.recordStop();
|
nextOnTap();
|
||||||
|
|
||||||
widget.onComplete(
|
|
||||||
MediaResult(
|
|
||||||
fileValue:
|
|
||||||
await File(directory!).readAsBytes(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
width:
|
width:
|
||||||
MediaQuery.of(context).size.width * 0.3,
|
MediaQuery.of(context).size.width *
|
||||||
|
0.3,
|
||||||
height: 45,
|
height: 45,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xFFD8D8D8),
|
color: const Color(0xFFD8D8D8),
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius:
|
||||||
|
BorderRadius.circular(15),
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Next',
|
'Next',
|
||||||
style: Theme.of(context).textTheme.button,
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.button,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -257,6 +257,75 @@ class _RecorderState extends ConsumerState<Recorder> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playOnTap() {
|
||||||
|
if (recording) {
|
||||||
|
widget.audioService.recordStop();
|
||||||
|
|
||||||
|
clock.stopClock();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
recording = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
widget.audioService.recordStart();
|
||||||
|
|
||||||
|
clock.startClock();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
recording = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextOnTap() async {
|
||||||
|
widget.audioService.recordStop();
|
||||||
|
|
||||||
|
widget.onComplete(
|
||||||
|
MediaResult(
|
||||||
|
fileValue: await File(directory!).readAsBytes(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used by [MediaPickerInputAudio] to set styling options.
|
||||||
|
///
|
||||||
|
/// background can be set to determine the background of the page.
|
||||||
|
///
|
||||||
|
/// pageContent can be set to set any widget at the top of the page.
|
||||||
|
///
|
||||||
|
/// timeTextStyle sets the [TextStyle] of the time that shows the recording duration. Defaults to headline5.
|
||||||
|
///
|
||||||
|
/// playButton changes the default play/pause button.
|
||||||
|
///
|
||||||
|
/// nextButton changes the default next/finish button.
|
||||||
|
class AudioInputStyling {
|
||||||
|
AudioInputStyling({
|
||||||
|
this.background,
|
||||||
|
this.pageContent,
|
||||||
|
this.timeTextStyle,
|
||||||
|
this.playButton,
|
||||||
|
this.nextButton,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// background can be set to determine the background of the page.
|
||||||
|
final Widget? background;
|
||||||
|
|
||||||
|
/// pageContent can be set to set any widget at the top of the page.
|
||||||
|
final Widget? pageContent;
|
||||||
|
|
||||||
|
/// timeTextStyle sets the [TextStyle] of the time that shows the recording duration. Defaults to headline5.
|
||||||
|
final TextStyle? timeTextStyle;
|
||||||
|
|
||||||
|
/// playButton changes the default play/pause button.
|
||||||
|
final Widget Function(bool recording, Function onTap)? playButton;
|
||||||
|
|
||||||
|
/// nextButton changes the default next/finish button.
|
||||||
|
final Widget Function(bool recording, Function onTap)? nextButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic clock class can be created and used to keep the time.
|
/// Generic clock class can be created and used to keep the time.
|
||||||
|
|
Loading…
Reference in a new issue