I'm using the Chewie Video player in my Flutter app. How to check when playback has completed, so that I can close the screen and dispose?
You can copy paste run full code below
You can check position and duration
full code is official example set loop to false and add the following code snippet
code snippet
_videoPlayerController1.addListener(() {
if (_videoPlayerController1.value.position ==
_videoPlayerController1.value.duration) {
print('video Ended');
}
});
Output
I/flutter ( 4881): video Ended
full code
import 'package:chewie/chewie.dart';
import 'package:chewie/src/chewie_player.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(
ChewieDemo(),
);
}
class ChewieDemo extends StatefulWidget {
ChewieDemo({this.title = 'Chewie Demo'});
final String title;
#override
State<StatefulWidget> createState() {
return _ChewieDemoState();
}
}
class _ChewieDemoState extends State<ChewieDemo> {
TargetPlatform _platform;
VideoPlayerController _videoPlayerController1;
VideoPlayerController _videoPlayerController2;
ChewieController _chewieController;
#override
void initState() {
super.initState();
_videoPlayerController1 = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4');
_videoPlayerController2 = VideoPlayerController.network(
'https://www.sample-videos.com/video123/mp4/480/asdasdas.mp4');
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController1,
aspectRatio: 3 / 2,
autoPlay: true,
looping: false,
// Try playing around with some of these other options:
// showControls: false,
// materialProgressColors: ChewieProgressColors(
// playedColor: Colors.red,
// handleColor: Colors.blue,
// backgroundColor: Colors.grey,
// bufferedColor: Colors.lightGreen,
// ),
// placeholder: Container(
// color: Colors.grey,
// ),
// autoInitialize: true,
);
_videoPlayerController1.addListener(() {
if (_videoPlayerController1.value.position ==
_videoPlayerController1.value.duration) {
print('video Ended');
}
});
}
#override
void dispose() {
_videoPlayerController1.dispose();
_videoPlayerController2.dispose();
_chewieController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: widget.title,
theme: ThemeData.light().copyWith(
platform: _platform ?? Theme.of(context).platform,
),
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: <Widget>[
Expanded(
child: Center(
child: Chewie(
controller: _chewieController,
),
),
),
FlatButton(
onPressed: () {
_chewieController.enterFullScreen();
},
child: Text('Fullscreen'),
),
Row(
children: <Widget>[
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_chewieController.dispose();
_videoPlayerController2.pause();
_videoPlayerController2.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController1,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
child: Text("Video 1"),
padding: EdgeInsets.symmetric(vertical: 16.0),
),
),
),
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_chewieController.dispose();
_videoPlayerController1.pause();
_videoPlayerController1.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController2,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text("Error Video"),
),
),
)
],
),
Row(
children: <Widget>[
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_platform = TargetPlatform.android;
});
},
child: Padding(
child: Text("Android controls"),
padding: EdgeInsets.symmetric(vertical: 16.0),
),
),
),
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_platform = TargetPlatform.iOS;
});
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text("iOS controls"),
),
),
)
],
)
],
),
),
);
}
}
Related
I applied will pop scope on that screen it didn't work me its YouTube video player screen. I define all the routes in main.dart is that problem will pop scope is not working Let me know where I am going wrong
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stocker/models/YouTubeStateModel.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
class VideoPlayer extends StatefulWidget {
const VideoPlayer({
Key? key,
required this.videoID,
required this.data,
}) : super(key: key);
static const routeName = '/videoPlayer';
final YouTubeState data;
final String videoID;
#override
State<VideoPlayer> createState() => _VideoPlayerState();
}
class _VideoPlayerState extends State<VideoPlayer> {
late YoutubePlayerController _controller;
#override
void initState() {
super.initState();
_controller = YoutubePlayerController(
initialVideoId: widget.videoID,
flags: const YoutubePlayerFlags(
autoPlay: true,
mute: false,
),
);
Future.delayed(
const Duration(milliseconds: 300),
).then((value) {
_controller.toggleFullScreenMode();
_controller.setSize(Size(1.sw, 1.sh));
});
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;
_controller.setSize(
width > height
? Size(1.sw - ScreenUtil().statusBarHeight, 1.sh)
: Size(1.sw, 1.sh - ScreenUtil().statusBarHeight),
);
return WillPopScope(
onWillPop: () async {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
Navigator.of(context).pop();
return false;
},
child: Stack(
children: [
YoutubePlayerBuilder(
player: YoutubePlayer(
bottomActions: [
const SizedBox(width: 14.0),
CurrentPosition(),
const SizedBox(width: 8.0),
ProgressBar(
isExpanded: true,
// colors: widget,
),
RemainingDuration(),
const PlaybackSpeedButton(),
],
// aspectRatio: width > height
// ? (width - ScreenUtil().statusBarHeight) / height
// : (width) / (height - ScreenUtil().statusBarHeight),
aspectRatio: width > height
? height / (width - ScreenUtil().statusBarHeight)
: (height - ScreenUtil().statusBarHeight) / (width),
controller: _controller,
width: size.width,
),
builder: (context, player) {
return Scaffold(
backgroundColor: Colors.black,
body: Padding(
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight),
child: SizedBox(
height: 1.sh - ScreenUtil().statusBarHeight,
width: 1.sw,
child: Stack(
children: [
Center(child: player),
// Positioned(
// bottom: 100,
// right: 100,
// child: GestureDetector(
// onTap: Navigator.of(context).pop,
// child: SvgPicture.asset(
// 'assets/svg/back_arrow.svg',
// color: Colors.white,
// width: 24.h,
// height: 24.h,
// ),
// ),
// ),
],
),
),
),
);
},
),
Positioned(
left: 5.w,
top: 30.h,
child: GestureDetector(
onTap: () {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
Navigator.of(context).pop();
},
child: SvgPicture.asset(
'assets/svg/back_arrow.svg',
color: Colors.white,
width: 16.w,
height: 16.w,
),
),
)
],
),
);
}
}
I applied Will pop scope on the main stack and inside the builder Scaffold as well but at both of the places it didn't work let me know how can I tackle this problem .
/* ::::::::::::::::::::::: OnWillPop show dialog :::::::::::::::::::::::*/
WillPopScope(
onWillPop: () {
return openDialog();
},)
openDialog() {
Get.dialog(
AlertDialog(
title: const Text('Are Yor Sure?'),
content: const Text('Do you want to exit this App'),
actions: [
TextButton(
onPressed: () => Get.back(),
child: const Text("No"),
),
TextButton(
onPressed: () {
if (Platform.isAndroid) {
SystemNavigator.pop(); // or
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(builder: (context) => HomePage()),
// (route) => false);
print("android>>>>");
} else if (Platform.isIOS) {
exit(0);
}
},
child: const Text("Yes"),
),
],
),
);
}
2nd way
onWillPop: () async {
final shouldPop = await showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Do you want to go back?'),
actionsAlignment: MainAxisAlignment.spaceBetween,
actions: [
TextButton(
onPressed: () {
Navigator.pop(context, true);
},
child: const Text('Yes'),
),
TextButton(
onPressed: () {
Navigator.pop(context, false);
},
child: const Text('No'),
),
],
);
},
);
return shouldPop!;
},
I copy example and try to do some modify, however I notice that the player controls unable to click / seek
video_player: ^2.4.5
chewie: ^1.3.4
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class VideoView extends StatefulWidget {
const VideoView({
Key? key,
}) : super(key: key);
#override
State<StatefulWidget> createState() {
return _VideoViewState();
}
}
class _VideoViewState extends State<VideoView> {
late VideoPlayerController _videoPlayerController;
ChewieController? _chewieController;
int? bufferDelay;
#override
void initState() {
super.initState();
initializePlayer();
}
#override
void dispose() {
_videoPlayerController.dispose();
_chewieController?.dispose();
super.dispose();
}
List<String> srcs = [
"https://assets.mixkit.co/videos/preview/mixkit-spinning-around-the-earth-29351-large.mp4",
"https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4",
"https://assets.mixkit.co/videos/preview/mixkit-a-girl-blowing-a-bubble-gum-at-an-amusement-park-1226-large.mp4"
];
Future<void> initializePlayer() async {
_videoPlayerController = VideoPlayerController.network(srcs[currPlayIndex]);
await Future.wait([
_videoPlayerController.initialize(),
]);
_createChewieController();
setState(() {});
}
void _createChewieController() {
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
autoPlay: true,
looping: true,
progressIndicatorDelay: Duration(seconds: 1),
additionalOptions: (context) {
return <OptionItem>[
OptionItem(
onTap: toggleVideo,
iconData: Icons.live_tv_sharp,
title: 'Toggle Video Src',
),
];
},
customControls: MaterialControls(
showPlayButton: true,
),
hideControlsTimer: const Duration(seconds: 3),
// materialProgressColors: ChewieProgressColors(
// playedColor: Colors.red,
// handleColor: Colors.blue,
// backgroundColor: Colors.grey,
// bufferedColor: Colors.lightGreen,
// ),
// placeholder: Container(
// color: Colors.grey,
// ),
// autoInitialize: true,
);
}
int currPlayIndex = 0;
Future<void> toggleVideo() async {
await _videoPlayerController.pause();
currPlayIndex += 1;
if (currPlayIndex >= srcs.length) {
currPlayIndex = 0;
}
await initializePlayer();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
brightness: Brightness.light,
colorScheme: const ColorScheme.light(secondary: Colors.red),
disabledColor: Colors.grey.shade400,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
splashRadius: 10.sp,
icon: Container(
height: kToolbarHeight,
width: kToolbarHeight,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(100)
),
child: Icon(Icons.arrow_back_rounded, color: Colors.white, size: 22.sp)
),
onPressed: (){
Navigator.pop(context);
},
),
),
extendBody: true,
extendBodyBehindAppBar: true,
body: Column(
children: <Widget>[
Expanded(
child: Center(
child: _chewieController != null && _chewieController!.videoPlayerController.value.isInitialized ?
Chewie(
controller: _chewieController!,
)
:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(),
SizedBox(height: 20),
Text('Loading'),
],
),
),
),
SizedBox(height: 100.sp,)
],
),
),
);
}
}
remove these ....
extendBody: true,
extendBodyBehindAppBar: true,
Hello friends my problem is that I want perform task there small icon on menu bar mic icon when user click on Mic it show dialog box and when they speak text word appear on dialog box when user finished up there speech it's goes to next screen I have done all thing but problem is that when user finishing there speech i unable to go on next sacreen this only issue any expert can help here is picture below what i actually i want
Here is when user speech
When they complete their speech go next sacreen
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;
import 'package:speech_to_text/speech_to_text.dart';
import 'package:avatar_glow/avatar_glow.dart';
class Booknames extends StatefulWidget {
const Booknames({Key? key}) : super(key: key);
#override
_BooknamesState createState() => _BooknamesState();
}
class _BooknamesState extends State<Booknames> {
stt.SpeechToText speechToText = stt.SpeechToText();
bool islistening = false;
late String text = 'Example:Gensis chapter verse 5';
bool complete=false;
#override
void initState() {
// TODO: implement initState
super.initState();
_initSpeech();
}
/// This has to happen only once per app
void _initSpeech() async {
speechToText.initialize();
}
final GlobalKey _dialogKey = GlobalKey();
_showDialog() async {
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return StatefulBuilder(
key: _dialogKey,
builder: (context, setState) {
return Container(
child: Dialog(
child: Padding(
padding: EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
AvatarGlow(
glowColor: Colors.blue,
endRadius: 80,
duration: Duration( milliseconds: 2500),
repeat: true,
showTwoGlows: true,
repeatPauseDuration: Duration( milliseconds: 150),
child: Material(
elevation: 5,
shape: CircleBorder(),
child: CircleAvatar(
backgroundColor: Colors.white,
child: Icon(Icons.mic, color: Colors.blue, size: 40,),
radius: 40,
),
),
),
Text(text),
SizedBox(height: 10),
TextButton(
onPressed: () => Navigator.pop(context, false), // passing false
child: Text('Cancel Voice'),
),
],
),
),
),
);
},
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
new IconButton(
icon: new Icon(islistening ? Icons.mic : Icons.mic_none),
highlightColor: Colors.pink,
onPressed: () {
setState(() {
_listen();
_showDialog();
});
},
),
],
elevation: 0,
title: Text('The Bible Multiversion', style: TextStyle(
fontSize: 20
),),
centerTitle: true,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView.separated(
shrinkWrap: true,
itemCount: 1,
separatorBuilder: (BuildContext context, int index) =>
Divider(height: 1),
itemBuilder: (context, index) {
return Column(
children: [
],
);
},
),
),
],
),
);
}
void _listen() async {
if (!islistening) {
bool available = await speechToText.initialize(
onStatus: (val) => print('onStatus: $val'),
onError: (val) => print('onError: $val'),
);
if (available) {
setState(() {
islistening = true;
});
speechToText.listen(
onResult: (result) =>
setState(() {
text = result.recognizedWords;
if (_dialogKey.currentState != null && _dialogKey.currentState!.mounted) {
_dialogKey.currentState!.setState(() {
text =result.recognizedWords;
});
}
})
);
}
} else {
setState(() => islistening = false
);
speechToText.stop();
}
}
}
I have created this video player for my application which can play video from assets. Since, It is made from (video_player) package I guess I can play only one video with it But I want 3-4 videos to be played. How can I do that? It is possible or not...Help me! Furthermore, I also want to make the video the option of 10 seconds backward and forward while pressing it's sides. Thanks for your help!
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(VideoPlay());
}
class VideoPlay extends StatefulWidget {
String? pathh;
#override
_VideoPlayState createState() => _VideoPlayState();
VideoPlay({
this.pathh = "assets/video.mp4", // Video from assets folder
});
}
class _VideoPlayState extends State<VideoPlay> {
late VideoPlayerController controller;
late Future<void> futureController;
#override
void initState() {
//url to load network
controller = VideoPlayerController.asset(widget.pathh!);
futureController = controller.initialize();
controller.setLooping(true);
controller.setVolume(25.0);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FutureBuilder(
future: futureController,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: VideoPlayer(controller));
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
),
),
Padding(
padding: const EdgeInsets.all(6.0),
child: RaisedButton(
color: Color(0xff9142db),
child: Icon(
controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
),
onPressed: () {
setState(() {
if (controller.value.isPlaying) {
controller.pause();
} else {
controller.play();
}
});
},
),
)
],
));
}
}
App Image Is Here
I like your idea and wanted to deal with it, this is the result.
I hope you can do better.
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main(List<String> args) {
runApp(Example());
}
class Example extends StatelessWidget {
const Example({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
color: Colors.white,
debugShowCheckedModeBanner: false,
home: VideoPlayersList(),
);
}
}
class VideoPlayersList extends StatelessWidget {
const VideoPlayersList({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
List<String> paths = [
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
];
return Scaffold(
body: SingleChildScrollView(
child: Column(children: [
ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: paths.length,
itemBuilder: (BuildContext context, int index) {
return VideoPlay(
pathh: paths[index],
);
},
),
]),
),
);
}
}
class VideoPlay extends StatefulWidget {
String? pathh;
#override
_VideoPlayState createState() => _VideoPlayState();
VideoPlay({
Key? key,
this.pathh, // Video from assets folder
}) : super(key: key);
}
class _VideoPlayState extends State<VideoPlay> {
ValueNotifier<VideoPlayerValue?> currentPosition = ValueNotifier(null);
VideoPlayerController? controller;
late Future<void> futureController;
initVideo() {
controller = VideoPlayerController.asset(widget.pathh!);
futureController = controller!.initialize();
}
#override
void initState() {
initVideo();
controller!.addListener(() {
if (controller!.value.isInitialized) {
currentPosition.value = controller!.value;
}
});
super.initState();
}
#override
void dispose() {
controller!.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: futureController,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator.adaptive();
} else {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: SizedBox(
height: controller!.value.size.height,
width: double.infinity,
child: AspectRatio(
aspectRatio: controller!.value.aspectRatio,
child: Stack(children: [
Positioned.fill(
child: Container(
foregroundDecoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black.withOpacity(.7),
Colors.transparent
],
stops: [
0,
.3
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter),
),
child: VideoPlayer(controller!))),
Positioned.fill(
child: Column(
children: [
Expanded(
flex: 8,
child: Row(
children: [
Expanded(
flex: 3,
child: GestureDetector(
onDoubleTap: () async {
Duration? position =
await controller!.position;
setState(() {
controller!.seekTo(Duration(
seconds: position!.inSeconds - 10));
});
},
child: const Icon(
Icons.fast_rewind_rounded,
color: Colors.black,
size: 40,
),
),
),
Expanded(
flex: 4,
child: IconButton(
icon: Icon(
controller!.value.isPlaying
? Icons.pause
: Icons.play_arrow,
color: Colors.black,
size: 40,
),
onPressed: () {
setState(() {
if (controller!.value.isPlaying) {
controller!.pause();
} else {
controller!.play();
}
});
},
)),
Expanded(
flex: 3,
child: GestureDetector(
onDoubleTap: () async {
Duration? position =
await controller!.position;
setState(() {
controller!.seekTo(Duration(
seconds: position!.inSeconds + 10));
});
},
child: const Icon(
Icons.fast_forward_rounded,
color: Colors.black,
size: 40,
),
),
),
],
),
),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.bottomCenter,
child: ValueListenableBuilder(
valueListenable: currentPosition,
builder: (context,
VideoPlayerValue? videoPlayerValue, w) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
child: Row(
children: [
Text(
videoPlayerValue!.position
.toString()
.substring(
videoPlayerValue.position
.toString()
.indexOf(':') +
1,
videoPlayerValue.position
.toString()
.indexOf('.')),
style: const TextStyle(
color: Colors.white,
fontSize: 22),
),
const Spacer(),
Text(
videoPlayerValue.duration
.toString()
.substring(
videoPlayerValue.duration
.toString()
.indexOf(':') +
1,
videoPlayerValue.duration
.toString()
.indexOf('.')),
style: const TextStyle(
color: Colors.white,
fontSize: 22),
),
],
),
);
}),
))
],
),
),
])),
),
);
}
},
);
}
}
When I made my first project about a news app, I got an error.
this is my code
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:last_news/state.dart';
import 'package:webview_flutter/webview_flutter.dart';
class NewsDetail extends StatefulWidget {
#override
State<NewsDetail> createState() => _NewsDetailState();
}
class _NewsDetailState extends State<NewsDetail> {
double progress = 0;
final Completer<WebViewController> _controller = Completer<WebViewController>();
#override
void initState() {
// TODO: implement initState
super.initState();
if(Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
#override
void dispose() {
// TODO: implement dispose
super.dispose();
}
#override
Widget build(BuildContext context,) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: Color(0xFFA51234)));
return MaterialApp(
home: Scaffold(
body: SafeArea(child: Container(child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(children: [
IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: Icon(Icons.arrow_back, color:Colors.black),
alignment: Alignment.topLeft,)
],),
Container(
padding: EdgeInsets.all(10.0),
child: progress < 1.0 ? LinearProgressIndicator(value: progress) : Container(),
),
Expanded(child: WebView(
initialUrl: context.read(urlState).state,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) {
_controller.complete(controller);
},
),)
],),)),),
);
}
}
I got this error on initialUrl: context.read(urlState).state,
Too many positional arguments: 0 expected, but 1 found.
Try removing the extra arguments.
This code urlState
import 'package:flutter_riverpod/flutter_riverpod.dart';
final urlState = StateProvider(((ref) => ''));
Please help me to fix this
I tried adding import 'package:flutter_bloc/flutter_bloc.dart'; because the "context.read" have a red underline. And then, the "urlState" have a red underline.
Another Error code on HomePage
import 'dart:io';
import 'package:bubble_tab_indicator/bubble_tab_indicator.dart';
import 'package:carousel_slider/carousel_options.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:last_news/article.dart';
import 'package:last_news/network/api_request.dart';
import 'package:last_news/news.dart';
import 'package:last_news/state.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod/riverpod.dart';
class Home extends StatefulWidget {
Home({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> with SingleTickerProviderStateMixin{
final List<Tab> tabs = <Tab>[
new Tab(text: 'General'),
new Tab(text: 'Technology'),
new Tab(text: 'Sport'),
new Tab(text: 'Business'),
new Tab(text: 'Entertainment'),
new Tab(text: 'Health'),
];
late TabController _tabController;
#override
void initState() {
// TODO: implement initState
super.initState();
_tabController = new TabController(length: tabs.length, vsync: this);
}
#override
void dispose() {
_tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('News App'),
bottom: TabBar(
isScrollable: true,
unselectedLabelColor: Colors.grey,
labelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.tab,
indicator: BubbleTabIndicator(
indicatorHeight: 25.0,
indicatorColor: Colors.blueAccent,
tabBarIndicatorSize: TabBarIndicatorSize.tab,
),
tabs: tabs,
controller: _tabController,
),
),
body: TabBarView(
controller: _tabController,
children: tabs.map((Tab){
return FutureBuilder(
future: fetchNewsByCategory(Tab.text!),
builder: (context, snapshot) {
if(snapshot.hasError)
return Center(child: Text('${snapshot.error}'),);
else if(snapshot.hasData)
{
var newsList = snapshot.data as News;
var sliderList = newsList.articles != null ?
newsList.articles!.length > 10 ?
newsList.articles!.getRange(0, 10).toList()
: newsList.articles!.take(newsList.articles!.length).toList()
: [];
var contentList = newsList.articles !=null ?
newsList.articles!.length > 10 ?
newsList.articles!.getRange(11, newsList.articles!.length - 1).toList()
: [] : [];
return SafeArea(child: Column(
children: [
CarouselSlider(
options: CarouselOptions(
aspectRatio: 16/9,
enlargeCenterPage: true,
viewportFraction: 0.8,
),
items: sliderList.map((item){
return Builder(builder: (context){
return GestureDetector(
onTap: () {
context.read(urlState).state = item.url;
Navigator.pushNamed(context, '/detail');
}, child: Stack(children: [
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
'${item.urlToImage}',
fit: BoxFit.cover,),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Color(0xAA333639),
child: Padding(
padding: const EdgeInsets.all(8), child:
Text('${item.title}',
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold
),
),
),
),
],
)
]),
);
});
}).toList(),
),
Divider(thickness: 3),
Padding(padding: const EdgeInsets.only(left: 8),
child: Text('Trending',
style: TextStyle(fontSize: 26,fontWeight: FontWeight.bold),
),
),
Divider(thickness: 3),
Expanded(child: ListView.builder(
itemCount: contentList.length,
itemBuilder:(context, index) {
return GestureDetector(onTap: (){
context.read(urlState).state = contentList[index].url;
Navigator.pushNamed(context, '/detail');
}, child:
ListTile(
leading: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network('${contentList[index].urlToImage}',
fit: BoxFit.cover,
height: 80,
width: 80,
),
),
title: Text('${contentList[index].title}',
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text('${contentList[index].publishedAt}',
style: TextStyle(fontStyle: FontStyle.italic)),
),);
}))
],
));
}
else return Center(child: CircularProgressIndicator(),);
});
}).toList(),
),
);
}
}
This error on
return Builder(builder: (context){
return GestureDetector(
onTap: () {
context.read(urlState).state = item.url;
Navigator.pushNamed(context, '/detail');
},
And
Expanded(child: ListView.builder(
itemCount: contentList.length,
itemBuilder:(context, index) {
return GestureDetector(onTap: (){
context.read(urlState).state = contentList[index].url;
Navigator.pushNamed(context, '/detail');
},
Both of these codes have the same error
The webview widget accepts initialUrl as a string, It has no any method as you added above.
Therefore the code could be written
Expanded(
child: WebView(
initialUrl: '', // This should be string so you can get data and convert it to string
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) {
_controller.complete(controller);
},
),
);