Flutter Carousel no Image and some other difficulties - flutter

I am new to flutter as well as app dev.
I was trying to implement a STAEFUL carousel that responds and redirects to a certain link when an image in the carousel is clicked.
Here are the problems I faced.
I am not getting how to make the carousel images stateful should I implement a Gesture detector or Inkwell?
Should Every image has to be tagged within the [LIST] or the entire carousel can be tagged with a single inkwell or gesture detector?
Please have a look in the code, is it possible to map the redirect addresses as a list! (This will be much easier to add images, but what is bothering me here is, do I have to recompile and upload the app to AppStore each time I add new image address and respective redirect link?)
Most importantly the carousel isn't showing the images only the URL
what do these mean in this part of the code?
[LIST].map((i) {}
and
'text $i'
items: [imgList].map((i) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(color: Colors.blueAccent),
child: Text('text $i', style: TextStyle(fontSize: 16.0),)
);
here is the entire code
import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
//import 'package:carousel_slider/carousel_controller.dart';
import 'package:carousel_slider/carousel_options.dart';
List<String> imgList =
[
'https://static.scientificamerican.com/sciam/cache/file/92E141F8-36E4-4331-BB2EE42AC8674DD3_source.jpg',
'https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png',
];
List<String> redirectList =
[
'img 1 redirect link',
'img 2 redirect link',
]; //yet to be configured
class VerticalSliderDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: CarouselSlider(
options: CarouselOptions(
aspectRatio: 2.0,
enlargeCenterPage: true,
scrollDirection: Axis.horizontal,
autoPlay: true,
autoPlayInterval: Duration(seconds: 3),
autoPlayAnimationDuration: Duration(milliseconds: 800),
autoPlayCurve: Curves.fastOutSlowIn,
),
items: [imgList].map((i) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(color: Colors.blueAccent),
child: Text('text $i', style: TextStyle(fontSize: 16.0),)
);
}
).toList(),
),
);
}
}

https://github.com/Amit506/courouselexample
in this link i have uploaded correct working courousel slider .
if you want to know the differenve between text widget and image widget you should refer to official documentation of flutter they have written all the information of widgets.
https://api.flutter.dev/flutter/widgets/Image-class.html
https://github.com/Amit506/dart-foods/blob/main/lib/TabBars.dart/TabBar1.dart
in this link i have used courousel builder in one of my project you can refer to it for advance courousel slider.

To make image responsive to tap you only have to wrap image widget with gesturedetector /inkwell or any other widgets available In this case you can wrap image.Network

You can't show picture in text widget.for showing image from url you have to use Image.Network () instead of text widget. text widget is used to show only text .
to show any network image you can do
Image.Network('url'). If u want i can can show you code

Related

Display multiple pages at the same time

I have an app with two features, that have routes such as:
/feature1
/feature1/a
/feature2
/feature2/a
/feature2/a/b
/feature2/c
I can use GoRouter and its ShellRoute to switch between these one at a time using context.goNamed('feature2'), which would replace the entire screen with feature 2 (when tapping a tab in a tab bar for example). Here's a diagram of just the top level routes using tabs:
However, I would like to have an overview style menu which displays multiple destinations at once, so the user can see where they will be going before they go there (for example the preview page tabs in a mobile web browser). Here's a diagram:
and then tapping on either of the two pages would make them full screen:
Pressing the menu button at the bottom would return you to the overview menu page.
One way I have thought about solving this would be to make static preview images out of the routes when the menu button is tapped, and just display the previews. But these won't be live, and I would like a more elegant approach that actually displays the live contents of the route if possible.
Another way I have thought about solving this would be to use a top level GoRouter and then two descendant GoRouters each containing just one branch of the routes. I'm not sure if multiple GoRouters would lead to problems with things like if I wanted to context.go() to another branch.
If the ShellRoute.builder gave me access to all of the child page's widgets, I could display them however I wanted, but it just provides a single child.
I have not worked with 'go_router' or 'ShellRoute.builder', but I like to make custom animated widgets like this for apps. It's also hard to explain how it would work in your app, but here is my take on this.
Try copy pasting this in an empty page. I have written some notes in code comments that might help explain things a little bit. And, this is not perfect but with more polishing according to the needs it could work.
class CustomPageView extends StatefulWidget {
const CustomPageView({Key? key}) : super(key: key);
#override
State<CustomPageView> createState() => _CustomPageViewState();
}
class _CustomPageViewState extends State<CustomPageView> {
// Scroll Controller required to control scroll via code.
// When user taps on the navigation buttons, we will use this controller
// to scroll to the next/previous page.
final ScrollController _scrollController = ScrollController();
// Saving screen width and height to use it for the page size and page offset.
double _screenWidth = 0;
double _screenHeight = 0;
// A bool to toggle between full screen mode and normal mode.
bool _viewFull = false;
#override
void initState() {
super.initState();
// Get the screen width and height.
// This will be used to set the page size and page offset.
// As of now, this only works when page loads, not when orientation changes
// or page is resized. That requires a bit more work.
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_screenWidth = MediaQuery.of(context).size.width;
_screenHeight = MediaQuery.of(context).size.height;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
// 'Column' to wrap the 'Body' and 'BottomNavigationBar'
body: Column(
children: [
// 'Expanded' to take up the remaining space after the 'BottomNavigationBar'
Expanded(
// A 'Container' to wrap the overall 'Body' and aligned to center.
// So when it resizes, it will be centered.
child: Container(
alignment: Alignment.center,
// 'AnimatedContainer' to animate the overall height of the 'Body'
// when user taps on the 'Full Screen' button.
child: AnimatedContainer(
duration: const Duration(milliseconds: 500),
height: _viewFull ? 200 : _screenHeight,
// A 'ListView' to display the pages.
// 'ListView' is used here because we want to scroll horizontally.
// It also enables us to use 'PageView' like functionality, but
// requires a bit more work, to make the pages snap after scrolling.
child: ListView(
controller: _scrollController,
scrollDirection: Axis.horizontal,
children: [
// A 'Container' to display the first page.
AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: _viewFull ? (_screenWidth / 2) - 24 : _screenWidth,
margin: _viewFull ? const EdgeInsets.all(12) : const EdgeInsets.all(0),
color: Colors.blue,
),
// A 'Container' to display the second page.
AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: _viewFull ? (_screenWidth / 2) - 24 : _screenWidth,
margin: _viewFull ? const EdgeInsets.all(12) : const EdgeInsets.all(0),
color: Colors.yellow,
),
],
),
),
),
),
// 'BottomNavigationBar' to show the navigation buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// 'Feature 1' button
GestureDetector(
onTap: () {
// Scroll to the first page
_scrollController.animateTo(
0,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
},
child: Container(
height: 60,
alignment: Alignment.center,
color: Colors.red,
padding: const EdgeInsets.all(12),
child: const Text('Feature 1'),
),
),
// 'Feature 2' button
GestureDetector(
onTap: () {
// Scroll to the second page
_scrollController.animateTo(
_screenWidth,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
},
child: Container(
height: 60,
alignment: Alignment.center,
color: Colors.green,
padding: const EdgeInsets.all(12),
child: const Text('Feature 2'),
),
),
// 'Full Screen' button
GestureDetector(
onTap: () {
// Toggle between full screen mode and normal mode
setState(() {
_viewFull = !_viewFull;
});
},
child: Container(
height: 60,
alignment: Alignment.center,
color: Colors.purple,
padding: const EdgeInsets.all(12),
child: const Text('View Full'),
),
),
],
),
],
),
);
}
}

Mouse scroll stuck while cursor is on top of youtube_player_iframe

Mouse scroll stuck on top of video. I'm using youtube_player_iframe. Also, I don't want to rebuild the iframe widget. I tried to wrap it with pointer_interceptor but it didn't solve the problem. My first priority is to solve the scroll issue and avoid rebuilding the widget on scrolling. Wrapping everything on SingleChildScrollView is not a good practice.
I don't want to use YouTube API like this package
Need to implemented flutter-web
if you have an alternative way to handle it, feel free to share.
Thanks
check this output video
Test widget
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:sliver_tools/sliver_tools.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';
class YoutubeVideoAdTestScreen2 extends StatefulWidget {
YoutubeVideoAdTestScreen2({Key? key}) : super(key: key);
#override
_YoutubeVideoAdTestScreen2State createState() =>
_YoutubeVideoAdTestScreen2State();
}
class _YoutubeVideoAdTestScreen2State extends State<YoutubeVideoAdTestScreen2> {
YoutubePlayerController _controller = YoutubePlayerController(
initialVideoId: '1oF3pI5umck',
params: YoutubePlayerParams(
// Defining custom playlist
startAt: Duration(seconds: 30),
showControls: true,
showFullscreenButton: true,
),
);
#override
void dispose() {
super.dispose();
_controller.close();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
MultiSliver(
children: [
...List.generate(
4,
(index) => Container(
color: index % 2 == 0 ? Colors.amber : Colors.cyanAccent,
height: index * 50 + 100,
),
).toList(),
SliverToBoxAdapter(
child: YoutubePlayerIFrame(
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{},
controller: _controller,
aspectRatio: 16 / 9,
),
),
...List.generate(
4,
(index) => Container(
color: index % 2 == 0 ? Colors.amber : Colors.cyanAccent,
height: index * 50 + 100,
),
).toList(),
],
),
],
),
);
}
}
The Problem with embedding HTML elements in your Flutter App is, that these are rendered differently. The dart api provides this information about iframes and their pointer events:
Due to security restrictions with cross-origin iframe elements, Flutter cannot dispatch pointer events to an HTML view. If an iframe is the target of an event, the window containing the is not notified of the event. In particular, this means that any pointer events which land on an iframe will not be seen by Flutter, and so the HTML view cannot participate in gesture detection with other widgets.
There is no ideal solution to this, either losing the ability to scroll when hovering the iframe, or to lose the ability to interact with the iframe, but still scroll over it.
The idea is simple: Wrap another AspectRatio in a PointerInterceptor, inside a Stack, so that the scrolling behaviour is still provided, but you sadly cannot interact with the iframe any more.
.....
SliverToBoxAdapter(
child: Stack(
children: [
YoutubePlayerIFrame(
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{},
controller: _controller,
aspectRatio: 16 / 9,
),
PointerInterceptor(
child: AspectRatio(
aspectRatio: 16 / 9,
),
),
],
),
),
......
There are surely different ways to implement this, butI found this to be the easiest if you just want to scroll over the iframe. The player can still be controlled via its _controller, so play(), stop() etc. still seem to work.
EDIT:
The PointerInterceptor is a pub.dev package: https://pub.dev/packages/pointer_interceptor

How to rotate a larger-than-screen image without the overflow being clipped off in Flutter?

I have this image that I would like to display full screen and rotate in the background:
Here it is filling the screen correctly:
The problem is, when it rotates, the sides have been clipped off:
I've tried every type of box fit. I've tried sizing the container width to double.infinity. I've tried wrapping the image in a SingleChildScrollView. I've tried putting overflow: Overflow.visible on the stack. All day trying things, but nothing seems to be working.
The image needs to continuously fill the screen while rotating. How can I code it so that the edges aren't clipped off?
Here's my code:
class FirstScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Stack(
children: <Widget>[
SpinPerfect(
infinite: true,
duration: Duration(seconds: 10),
child: Image.asset(
'assets/images/star-burst.png',
fit: BoxFit.none,
),
),
Container(
child: Center(
child: Text('This is Screen 1'),
),
),
],
),
),
);
}
}
Note: I am currently rotating it using SpinPerfect from the animate_do package, but the same clipping problem happens when using Transform.rotate.
Thanks in advance for any direction!
Here is a solution that works very well:
Use SpinPerfect from the animate_do package (https://pub.dev/packages/animate_do) in combination with the photo_view package (https://pub.dev/packages/photo_view).
SpinPerfect(
infinite: true,
spins: 1,
duration: Duration(seconds: 60),
child: PhotoView(
disableGestures: true,
backgroundDecoration: BoxDecoration(color: Colors.transparent),
initialScale: PhotoViewComputedScale.covered * 2.7,
imageProvider: AssetImage('assets/images/background.jpg'),
),
)
Thanks to the creator of the animate_do package for the idea. (Very cool dude!)

Carousel animation flutter with photos

I want to do a carousel animation with photos that starts by itself and doesn't need to be touch to move the photos (slide)and the photos to go to the right . The app that i am working in it's flutter .
You can use carousel_slider flutter package to achieve this. You can refer to the GitHub for documentation.
In Short,
Add carousel_slider: ^2.2.1 to your pubspec.yaml
import 'package:carousel_slider/carousel_slider.dart';
Simply create a CarouselSlider widget, and pass the required params:
pass autoPlay option as true on CarouselOptions()
CarouselSlider(
options: CarouselOptions(
height: 400.0,
enableInfiniteScroll: true,
autoPlay: true
),
items: [1,2,3,4,5].map((i) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Colors.amber
),
child: Text('text $i', style: TextStyle(fontSize: 16.0),)
);
},
);
}).toList(),
)

How to Navigate to other Screen using Carousel

I wanted to have a carousel with 5 photos and when I press any of the images I want to navigate to a different screen. I watched many videos but couldn't find any solutions. I used carousel_slider package.
CarouselSlider(
CarouselOptions(height: 400.0),
items: [1,2,3,4,5].map((i) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Colors.amber
),
child: Text('text $i', style: TextStyle(fontSize: 16.0),)
);
},
);
}).toList(),
)
Imagine I have 5 different pages and when I press any of the pictures in the carousel then I should be navigated to a particular page. If I use a Gesture detector how can I navigate him using navigator.push?
Try using ManuallyControlledSlider from
https://github.com/serenader2014/flutter_carousel_slider/blob/master/example/lib/main.dart but change onPressed callback inside
Iterable -> RaisedButton to navigate on specific page.