How to slow down scroll velocity in flutter - flutter

I am trying to implement a slower scroll velocity in carousel_slider widget, or some better snapping. the problem is that if the user does a very fast swipe motion a couple of items will be scrolled instead of snapping tot he next one. i want to eliminate that behavior.
I'm not sure if it helps but I'm adding the code bellow:
// Automatic FlutterFlow imports
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
class ModelCarousel extends StatefulWidget {
// final List<String> iconUrlList;
final double modelSize;
final Function(int index)? onItemTapped;
final int selectedIndex;
const ModelCarousel(
{Key? key,
// required this.iconUrlList,
required this.modelSize,
required this.selectedIndex,
this.onItemTapped})
: super(key: key);
#override
_ModelCarouselState createState() => _ModelCarouselState();
}
class _ModelCarouselState extends State<ModelCarousel> {
ScrollPhysics _scrollPhysics = const PageScrollPhysics();
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: Colors.red),
height: 350,
child: CarouselSlider.builder(
itemCount: 5,
options: CarouselOptions(
height: 400.0,
pageSnapping: true,
scrollPhysics: _scrollPhysics,
),
itemBuilder: (BuildContext context, int index, int pageViewIndex) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Colors.transparent,
image: DecorationImage(
image: AssetImage("assets/temp_images/model.png"),
fit: BoxFit.cover,
),
),
child: Text(
'text $index',
style: TextStyle(fontSize: 16.0),
));
})
);
}
Widget modelTile() {
return Padding(
padding: const EdgeInsets.fromLTRB(100, 0, 100, 0),
child: Container(
width: 200,
decoration: BoxDecoration(
color: Colors.transparent,
image: DecorationImage(
image: AssetImage("assets/temp_images/model.png"),
fit: BoxFit.cover,
),
),
),
);
}
}

i found a solution: I have changed the viewportFraction property to 0.98 for CarouselOptions class. this didn't change the speed but did have the desired effect, user now cant swipe more than one item.

Related

Custom widget, blur 2 widgets with text on front

I made my own widget with blur, bottom widget is looking correct, but top isn't. On top widget, text is behind blur, but why?
I need same result like second widget. (Text front of blur)
Second widget is looking correct.
Please look screenshot at first.
How to fix it? Thanks for any help.
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// incorrect
MyCard(
imageLink:
'https://catherineasquithgallery.com/uploads/posts/2021-02/1612198837_120-p-fioletovii-fon-mainkraft-160.png',
text: 'AR-scene',
),
SizedBox(
height: 70,
),
//correct
MyCard(
imageLink:
'https://www.digiseller.ru/preview/1019450/p1_3193057_f7ad4eea.jpg',
text: 'Photos',
),
],
),
);
}
}
// my custom widget
class MyCard extends StatelessWidget {
final imageLink;
final text;
const MyCard({Key? key, required this.imageLink, required this.text})
: super(key: key);
#override
Widget build(BuildContext context) {
return Container(
width: 270,
height: 320,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 4, sigmaY: 3),
child: Center(
child: Text(
text,
style: TextStyle(fontSize: 25, color: Colors.white),
textAlign: TextAlign.center,
),
)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
image: DecorationImage(
fit: BoxFit.cover, image: NetworkImage(imageLink))),
);
}
}
Wrap your BackdropFilter with ClipRect, else it covers the covering the full screen.
return Container(
key: ValueKey(text),
width: 270,
height: 320,
child: ClipRect( //<- here
child: BackdropFilter(
More on BackdropFilter-class
Using backdrop filter applies that particular filter to the whole screen. You can use ClipRRect to make it adopt the size of child widget (Container in this case).
// my custom widget
class MyCard extends StatelessWidget {
final imageLink;
final text;
const MyCard({Key? key, required this.imageLink, required this.text})
: super(key: key);
#override
Widget build(BuildContext context) {
return ClipRRect(
child: Container(
width: 270,
height: 320,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 4, sigmaY: 3),
child: Center(
child: Text(
text,
style: TextStyle(fontSize: 25, color: Colors.white),
textAlign: TextAlign.center,
),
)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
image: DecorationImage(
fit: BoxFit.cover, image: NetworkImage(imageLink))),
),
);
}
}
A better solution is to use ImageFiltered instead of BackdropFilter widget.
ImageFiltered blurs its child, for example, a single picture.
BackdropFilter blurs everything "behind" it, but does not blur its own child. It's useful in situations like a pop-up dialog, where you want to blur the whole screen, except the dialog itself.

Flutter: cannot create horizontally scrollable body with shown scroll bar

I need help to create scrollable body:
my screen
This is how my structure of body looks: build()
body: Padding(
padding: const EdgeInsets.all(30.0),
child: DragAndDropLists(
children: _contents,
onItemReorder: _onItemReorder,
onListReorder: _onListReorder,
axis: Axis.horizontal,
listWidth: 300,
listDraggingWidth: 300,
listPadding: EdgeInsets.all(20.0),
itemDivider: const Divider(
thickness: 4,
height: 10,
color: lightBlue,
),
itemDecorationWhileDragging: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: const Color(0xff004269).withOpacity(0.5),
spreadRadius: 2,
blurRadius: 3,
offset: const Offset(0, 0), // changes position of shadow
),
],
),
listInnerDecoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.all(Radius.circular(5)),
),
lastItemTargetHeight: 2,
addLastItemTargetHeightToTop: true,
lastListTargetSize: 40,
),
),
I tried already ListView, SingleChildScrollView, Column
I don't know why but it's doesn't work
Maybe somebody has an idea what I can change to see scrollbar and can scroll it horizontally
Thank you
You seem to be using a bit of complex layout, but a simplified version would look something like this:
You can set scrollDirection property of ListView to Axis.horizontal and for scrollbar you can wrap ListView inside Scrollbar.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final ScrollController _scrollController = ScrollController();
final List<int> _items = List<int>.generate(100, (int index) => index);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
height: 150,
child: Scrollbar(
isAlwaysShown: true,
controller: _scrollController,
child: ReorderableListView.builder(
scrollDirection: Axis.horizontal,
scrollController: _scrollController,
itemBuilder: buildItem,
itemCount: _items.length,
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
},
),
),
),
));
}
Widget buildItem(context, index) {
return Container(
key: Key('$index'),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.green[200],
),
margin: const EdgeInsets.all(8.0),
height: 100,
width: 100,
child: Center(child: Text('${_items[index]}')),
);
}
}
Ignore the handles, they only appear on desktop, drag and drop works on mobile devices.
Try wrap Padding in your Scaffold with SingleChildScrollView
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Padding(),
)
Other option that you can use is GridView, and ListView.

How to add swiper dots to the image

I am trying to add swiper dots below as shown in the figure
while in the code I tried parallax effect on image and text, now I am trying to add dots below, swiper dots will help to understand which page we are in.
here is the present code:
import 'package:ecommerce_int2/models/product.dart';
import 'package:flutter/material.dart';
import 'package:transformer_page_view/transformer_page_view.dart';
import 'package:flutter/cupertino.dart';
class ParallaxMain extends StatefulWidget {
ParallaxMain({Key key, this.title}) : super(key: key);
final String title;
#override
_ParallaxMainState createState() => new _ParallaxMainState();
}
class ParallaxSlide extends StatelessWidget {
final List<Product> product;
ParallaxSlide({Key key, this.product}) : super(key: key);
#override
Widget build(BuildContext context) {
return new TransformerPageView(
loop: true,
viewportFraction: 0.8,
transformer: new PageTransformerBuilder(
builder: (Widget child, TransformInfo info) {
return new Padding(
padding: new EdgeInsets.all(10.0),
child: new Material(
elevation: 4.0,
textStyle: new TextStyle(color: Colors.white),
borderRadius: new BorderRadius.circular(10.0),
child: new Stack(
fit: StackFit.expand,
children: <Widget>[
new ParallaxImage.asset(
//images[info.index],
product[info.index].image[0],
position: info.position,
),
new DecoratedBox(
decoration: new BoxDecoration(
gradient: new LinearGradient(
begin: FractionalOffset.bottomCenter,
end: FractionalOffset.topCenter,
colors: [
const Color(0xFF000000),
const Color(0x33FFC0CB),
],
),
),
),
new Positioned(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new ParallaxContainer(
child: new Text(
product[info.index].name,
style: new TextStyle(fontSize: 15.0),
),
position: info.position,
translationFactor: 300.0,
),
new SizedBox(
height: 8.0,
),
new ParallaxContainer(
child: new Text("₹ "+product[info.index].price.toString(),
style: new TextStyle(fontSize: 18.0)),
position: info.position,
translationFactor: 200.0,
),
],
),
left: 10.0,
right: 10.0,
bottom: 10.0,
)
],
),
),
);
}),
itemCount: product.length,
);
}
}
class _ParallaxMainState extends State<ParallaxMain> {
#override
Widget build(BuildContext context) {
return new SizedBox(
height: 400,
child: new ParallaxSlide()
);
}
}
Is there any way to add swiper dots to this code?
Try this:
move your TransformerPageView inside a stack and add a DotIndicator
Stack(children:[
TransformerPageView(controller: _controller),
DotsIndicator(controller: _controller)
])
Make sure you add the same _controller for both of them. Then position the dot indicator as you like.
PageController: A controller for PageView.
A page controller lets you manipulate which page is visible in a PageView.
You can read the complete information in the link provided.
Hints taken from here.
Personally, I use smooth_page_indicator because it provides awesome transition effects. Just follow the docs and it's so easy to implement.
Yes we can do it by using carousel_slider
Please check the example of Image carousel slider with a custom indicator.

Dart-How to toggle swiper on and off dynamically when the button is pressed?

I am using flutter_swiper to swipe images in my flutter application.I want to turn the swiper off when the button is pressed so, how can i do it in my existing code?
Here is my code:
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var eImage = [
"img/eyes/1.png",
"img/eyes/2.png",
"img/eyes/3.png",
];
double height = 200;
int itemNo;
double eh = 200;
double ew = 200;
double nh = 100;
double nw = 300;
double lh = 100;
double lw = 100;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("img/wal.jpg"),
fit: BoxFit.fill,
),
),
child: Container(
child: Stack(
children: <Widget>[
Align(
alignment: Alignment(0, -0.6),
child: Container(
width: ew,
height: eh,
//color: Colors.purple,
child: new SizedBox(
child: Swiper(
itemBuilder:
(BuildContext context, int index) {
return Image.asset(
eImage[index],
);
},
itemCount: eImage.length,
itemWidth: 200,
itemHeight: 200,
control: new SwiperControl(),
layout: SwiperLayout.DEFAULT,
customLayoutOption: CustomLayoutOption(
startIndex: 1, stateCount: 3) ///<--- here i am trying to start from 1st index
.addRotate([
0 / 180,
0.0,
0 / 180
]).addTranslate([
Offset(-400.0, 0.0),
Offset(0.0, 0.0),
Offset(370, -40.0),
]),
),
height: 200,
width: 350,
),
),
),
],
),
))));
}
}
In this code i am able to swipe images from list but i want to disable it when a button(not given in code) is pressed so, how to toggle ON/OFF this swiper on button click dynamically?
Just Consume the touch before it reaches the Swiper, using absorb pointer
Stack(
children: <Widget>[
TheSwiperWidget(),
AbsorbPointer(
absorbing: _disabled,
),
],
)
and in your button change the state
FlatButton(
onPressed: (){
setState(() {
_disabled = !=_disabled;
});
}, child: Text('Disable'),
)

How can i fix this SliverPersistentHeader Renderflexerror?

Gif of said error
I have a SliverPersistentHeader, that as a sliver does what it is supposed to do. However the content in the sliver causes renderflex errors.
How do i fix it, so that the content inside the sliver resizes with the sliver? I choose the SliverPersistentHeader to create a stack of headers, maybe there is another widget that would be more fitting?
The slivers are built in a CustomScrollView as objects in a list of slivers.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:weather/weather.dart';[enter image description here][1]
import 'dart:math' as math;
class TracksPage extends StatelessWidget{
TracksPage();
List tracks = List();
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
),
body: CollapsingList()
);
}}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
#required this.minHeight,
#required this.maxHeight,
#required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
#override
double get minExtent => minHeight;
#override
double get maxExtent => math.max(maxHeight, minHeight);
#override
Widget build(
BuildContext context,
double shrinkOffset,
bool overlapsContent)
{
return new SizedBox.expand(child: child);
}
#override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
class CollapsingList extends StatelessWidget {
SliverPersistentHeader makeHeader(List<int> sums, int tracks, DateTime day) {
return SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 0.0,
maxHeight: 80.0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey[400]),
color: Colors.white
),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.grey,
child: Text(tracks.toString(), style: TextStyle(color: Colors.black),),),
title: Text(" ${day.day}/${day.month}/${day.year}"),
subtitle: Row(children: <Widget>[
statCircle(Image.asset("assets/images/steps.png", height: 20, fit: BoxFit.cover,), [Color(0xFFC312E4), Color(0xFF841779)], sums[0].toString(), 0),
Padding(padding: EdgeInsets.only(right: 30),),
statCircle(Icon(Icons.timer, size: 15,), [Color(0xFF73E412), Color(0xFF5B9B1A)], "", 5),
Padding(padding: EdgeInsets.only(right: 30),),
statCircle(Icon(Icons.pin_drop, size: 15,), [Color(0xFF12D6E4), Color(0xFF118470)], sums[1].toString(), 5),]),
)
)
),
);
}
Column statCircle(Widget child, List<Color> colors, String info, double padding){
return Column(children: <Widget>[
Container(
child: child,
padding: EdgeInsets.all(7),
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: colors,
stops: [0.3, 0.6],
begin: Alignment.topCenter,
end: Alignment.bottomCenter
)
),
),
Padding(padding: EdgeInsets.only(bottom: padding),),
Text(info)
],);
}
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Firestore.instance.collection("collectionName").where("fieldName", isEqualTo:fieldVariable).snapshots(),
builder: (context, snapshot){
if(snapshot.hasData){
List dates = extractAndSort(snapshot);
return CustomScrollView(
slivers: makeSlivers(dates, context)
);
}
else return Container();
}
);
}
makeSlivers(List dates, BuildContext context){
List<Widget> slivers = new List<Widget>();
List totals = summarize(Globals.tracks);
int length;
if(Globals.tracks != null){
length = Globals.tracks.length;
} else length = 0;
slivers.add( makeCirclesHeader(totals[0], length, totals[1], context));
slivers.add(SliverPadding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
sliver: SliverToBoxAdapter(
child: Container(
height: 20,
color: Colors.white)
)
));
if(dates != null)
{dates.forEach((date) {
List tracks = Globals.tracks.where((track) => track.trackCreated.toDate().day == date.day).toList();
slivers.add(makeHeader(summarize(tracks), tracks.length, date));
slivers.add(sliverListDay(tracks));
});}
return slivers;
}
You need to wrap it like this: _SliverAppBarDelegate -> Container -> ClipRect -> OverflowBox -> ListTile
delegate: _SliverAppBarDelegate(
minHeight: 0.0,
maxHeight: 80.0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey[400]),
color: Colors.white
),
child: ClipRect(
child: OverflowBox(
alignment: Alignment.topLeft,
maxHeight: 80.0,
child: ListTile(
leading: CircleAvatar(
...