how to create ListView like given image - flutter

Blockquote
how to create list view like this how to create this type layout in flutter

you can copy the whole code in below
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late PageController controller;
double page = 0.0;
#override
void initState() {
super.initState();
controller = PageController(viewportFraction: 0.5)
..addListener(() {
setState(() {
page = controller.page!;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade100,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(26),
color: Colors.white,
),
child: Column(children: [
Text(
'head widgets',
style: TextStyle(
fontSize: 12,
color: Colors.grey.shade500,
),
),
Expanded(
child: PageView.builder(
controller: controller,
itemCount: pages.length,
itemBuilder: (context, index) {
if (index == page) {
return Transform.scale(
scale: 1,
child: pages[index],
);
} else if (index < page) {
return Transform.scale(
scale: max(1 - (page - index), 0.75),
child: pages[index],
);
} else {
return Transform.scale(
scale: max(1 - (index - page), 0.75),
child: pages[index],
);
}
},
),
),
Text(
'indicator',
style: TextStyle(fontSize: 12),
)
]),
),
),
);
}
List<Widget> pages = [
FlutterLogo(
size: 100,
),
FlutterLogo(
size: 100,
),
FlutterLogo(
size: 100,
),
];
}
and the result

Related

Flutter hero animation between widgets not screens

Hero animation is the best for navigating between screen, but I need same animation between widgets. Like one card moving another place for example: Product Card moves to shoppingcart and something else. Thanks for answers!
Try this one, add_to_cart_animation:
import 'package:add_to_cart_animation/add_to_cart_animation.dart';
import 'package:add_to_cart_animation/add_to_cart_icon.dart';
import 'package:flutter/material.dart';
import 'list_item.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Add To Cart Animation',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Add To Cart Animation'),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// We can detech the location of the card by this GlobalKey<CartIconKey>
GlobalKey<CartIconKey> gkCart = GlobalKey<CartIconKey>();
late Function(GlobalKey) runAddToCardAnimation;
var _cartQuantityItems = 0;
#override
Widget build(BuildContext context) {
return AddToCartAnimation(
// To send the library the location of the Cart icon
gkCart: gkCart,
rotation: true,
dragToCardCurve: Curves.easeIn,
dragToCardDuration: const Duration(milliseconds: 1000),
previewCurve: Curves.linearToEaseOut,
previewDuration: const Duration(milliseconds: 500),
previewHeight: 30,
previewWidth: 30,
opacity: 0.85,
initiaJump: false,
receiveCreateAddToCardAnimationMethod: (addToCardAnimationMethod) {
// You can run the animation by addToCardAnimationMethod, just pass trough the the global key of the image as parameter
this.runAddToCardAnimation = addToCardAnimationMethod;
},
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
centerTitle: false,
actions: [
// Improvement/Suggestion 4.4 -> Adding 'clear-cart-button'
IconButton(
icon: Icon(Icons.cleaning_services),
onPressed: () {
_cartQuantityItems = 0;
gkCart.currentState!.runClearCartAnimation();
},
),
SizedBox(width: 16),
AddToCartIcon(
key: gkCart,
icon: Icon(Icons.shopping_cart),
colorBadge: Colors.red,
),
SizedBox(
width: 16,
)
],
),
body: ListView(
children: [
AppListItem(onClick: listClick, index: 1),
AppListItem(onClick: listClick, index: 2),
AppListItem(onClick: listClick, index: 3),
AppListItem(onClick: listClick, index: 4),
AppListItem(onClick: listClick, index: 5),
AppListItem(onClick: listClick, index: 6),
AppListItem(onClick: listClick, index: 7),
],
),
),
);
}
// Improvement/Suggestion 4.4 -> Running AddTOCartAnimation BEFORE runCArtAnimation
void listClick(GlobalKey gkImageContainer) async {
await runAddToCardAnimation(gkImageContainer);
await gkCart.currentState!.runCartAnimation((++_cartQuantityItems).toString());
}
}
OR
[not null safety]
this is a sample of add to cart, add_cart_parabola:
import 'dart:ui';
import 'package:add_cart_parabola/add_cart_parabola.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
GlobalKey floatKey = GlobalKey();
GlobalKey rootKey = GlobalKey();
Offset floatOffset ;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
RenderBox renderBox = floatKey.currentContext.findRenderObject();
floatOffset = renderBox.localToGlobal(Offset.zero);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
key: rootKey,
width: double.infinity,
height: double.infinity,
color: Colors.grey,
child: ListView(
children: List.generate(40, (index){
return generateItem(index);
}).toList(),
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.yellow,
key: floatKey,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget generateItem(int index){
Text text = Text("item $index",style: TextStyle(fontSize:
25),);
Offset temp;
return GestureDetector(
onPanDown: (details){
temp = new Offset(details.globalPosition.dx, details.globalPosition
.dy);
},
onTap: (){
Function callback ;
setState(() {
OverlayEntry entry = OverlayEntry(
builder: (ctx){
return ParabolaAnimateWidget(rootKey,temp,floatOffset,
Icon(Icons.cancel,color: Colors.greenAccent,),callback,);
}
);
callback = (status){
if(status == AnimationStatus.completed){
entry?.remove();
}
};
Overlay.of(rootKey.currentContext).insert(entry);
});
},
child: Container(
color: Colors.orange,
child: text,
),
);
}
}
For animating widget in the same screen you can use AnimatedPositioned widget see the below code
import 'dart:math';
import 'package:flutter/material.dart';
class AnimatedPositionedDemo extends StatefulWidget {
const AnimatedPositionedDemo({Key? key}) : super(key: key);
static String routeName = 'animated_positioned';
#override
_AnimatedPositionedDemoState createState() => _AnimatedPositionedDemoState();
}
class _AnimatedPositionedDemoState extends State<AnimatedPositionedDemo> {
late double topPosition;
late double leftPosition;
double generateTopPosition(double top) => Random().nextDouble() * top;
double generateLeftPosition(double left) => Random().nextDouble() * left;
#override
void initState() {
super.initState();
topPosition = generateTopPosition(30);
leftPosition = generateLeftPosition(30);
}
void changePosition(double top, double left) {
setState(() {
topPosition = generateTopPosition(top);
leftPosition = generateLeftPosition(left);
});
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final appBar = AppBar(title: const Text('AnimatedPositioned'));
final topPadding = MediaQuery.of(context).padding.top;
// AnimatedPositioned animates changes to a widget's position within a Stack
return Scaffold(
appBar: appBar,
body: SizedBox(
height: size.height,
width: size.width,
child: Stack(
children: [
AnimatedPositioned(
top: topPosition,
left: leftPosition,
duration: const Duration(seconds: 1),
child: InkWell(
onTap: () => changePosition(
size.height -
(appBar.preferredSize.height + topPadding + 50),
size.width - 150),
child: Container(
alignment: Alignment.center,
width: 150,
height: 50,
child: Text(
'Click Me',
style: TextStyle(
color:
Theme.of(context).buttonTheme.colorScheme!.onPrimary,
),
),
color: Theme.of(context).primaryColor,
),
),
),
],
),
),
);
}
}
I hope it works for you
For Animated widgets, flutter team has provided a video on youtube here
And you can read all about them on their website here

Open a modal or a dialogue after navigation in Flutter

After calling Navigator pushReplacement, I arrive at a screen where I'd like to open a modal or a dialog automatically after the screen loads. I'm trying to do that using Timer.run inside initState() but it doesn't work, it doesn't show any errors as well. Could anyone help me understand what am I missing here?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:async';
class AfterSplash extends StatefulWidget {
#override
_AfterSplashState createState() => _AfterSplashState();
}
class _AfterSplashState extends State<AfterSplash> {
void initState() {
super.initState();
Timer.run(() {
showDialog(
context: context,
builder: (_) => AlertDialog(title: Text("Dialog title")),
);
});
}
#override
Widget build(BuildContext context) {
return opacityLogoTitle();
}
}
Widget opacityLogoTitle() {
return Scaffold(
body: Opacity(
opacity: 0.5,
child: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
child: Image(image: AssetImage('assets/images/main.png')),
),
),
),
Text(
'Sample App',
style: TextStyle(
fontFamily: 'SF Pro Display',
fontSize: 60,
color: Color.fromRGBO(105, 121, 248, 1),
),
),
],
),
),
),
);
}
It's my test code with your code.
It works well.
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: AfterSplash(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class AfterSplash extends StatefulWidget {
#override
_AfterSplashState createState() => _AfterSplashState();
}
class _AfterSplashState extends State<AfterSplash> {
void initState() {
super.initState();
Timer.run(() {
showDialog(
context: context,
builder: (_) => AlertDialog(title: Text("Dialog title")),
);
});
}
#override
Widget build(BuildContext context) {
return opacityLogoTitle();
}
}
Widget opacityLogoTitle() {
return Scaffold(
body: Opacity(
opacity: 0.5,
child: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(child: Text('asdf')),
),
),
Text(
'Sample App',
style: TextStyle(
fontFamily: 'SF Pro Display',
fontSize: 60,
color: Color.fromRGBO(105, 121, 248, 1),
),
),
],
),
),
),
);
}

How to change TabBar indicator color when swiping (Flutter)

Is it possible to change the TabBar indicator programmatically when swiping?
I've tried using a builder to get the index but I haven't had any luck .. I'm sure there must be a way to do this but haven't figured it out yet
Color _indicatorColor(index) {
switch (index) {
case 0:
return Colors.purple;
break;
case 1:
return colorInfoLighter;
break;
case 2:
return Colors.pink;
break;
}
}
Widget _buildScreen() {
var index;
return Scaffold(
appBar: AppBar(),
bottomNavigationBar: TabBar(
onTap: (_) {
setState(() {});
},
indicatorWeight: 4,
indicatorColor: _indicatorColor(index),
tabs: [
_requestedLabel(),
_completedLabel(),
_cancelledLabel(),
]),
body: Container(
child: TabBarView(children: [
_requestedTab(),
_completedTab(),
_cancelledTab(),
]),
),
);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: _buildScreen(),
);
}
Did you mean by changing tabs?
import 'dart:math';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({
Key key,
}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
final colors = [Colors.purple, Colors.green, Colors.pink];
Color indicatorColor;
TabController _controller;
#override
void initState() {
super.initState();
_controller = TabController(length: 3, vsync: this)
..addListener(() {
setState(() {
indicatorColor = colors[_controller.index];
});
});
indicatorColor = colors[0];
}
Widget _buildScreen() {
return Scaffold(
appBar: AppBar(),
bottomNavigationBar: Container(
color: Colors.blue,
child: TabBar(
labelColor: Colors.black,
controller: _controller,
indicatorWeight: 4,
indicatorColor: indicatorColor,
tabs: [
Tab(
child: Container(
child: Text('A'),
),
),
Tab(
child: Text('B'),
),
Tab(
child: Text('C'),
),
]),
),
body: Container(
child: TabBarView(
controller: _controller,
children: [
Center(
child: Text('aa'),
),
Center(
child: Text('bb'),
),
Center(
child: Text('cc'),
),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: _buildScreen(),
);
}
}

Flutter: canĀ“t open the CustomPainter class

I have a problem to implement the CustomPainter class, don't know my mistake in every single tutorial they did the same like me hope someone know the solution.
class _MyHomepageState extends State<MyHomepage> {
var _name;
final nameCon = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'App',
style: TextStyle(fontWeight: FontWeight.w900),
),
backgroundColor: Colors.brown[500],
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: nameCon,
decoration: InputDecoration(hintText: "Name"),
),
RaisedButton(
onPressed: () {
setState(() {
_name = nameCon.text;
});
},
child: Text("Los"),
),
Text("hier $_name "),
Expanded(
child: LayoutBuilder(
builder: (_, constraints) => Container(
width: constraints.widthConstraints().maxWidth,
height: constraints.heightConstraints().maxHeight,
color: Colors.yellow,
child: CustomPaint(painter: Thermometer()),
),
),
),
],
),
),
),
);
}
}
class Thermometer extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.brown
..style = PaintingStyle.stroke
..style=PaintingStyle.fill
..strokeWidth = 4;
canvas.drawRRect(
RRect.fromRectAndRadius(Rect.fromLTWH(-140, -60, 40, 290),
Radius.circular(20)),
paint,);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false ;
}
You can copy paste run full code below
please change left from -140 to 0 or other value
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(0, -60, 40, 290), Radius.circular(20)),
paint,
);
working demo
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomepage(title: 'Flutter Demo Home Page'),
);
}
}
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 _name;
final nameCon = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'App',
style: TextStyle(fontWeight: FontWeight.w900),
),
backgroundColor: Colors.brown[500],
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: nameCon,
decoration: InputDecoration(hintText: "Name"),
),
RaisedButton(
onPressed: () {
setState(() {
_name = nameCon.text;
});
},
child: Text("Los"),
),
Text("hier $_name "),
Expanded(
child: LayoutBuilder(
builder: (_, constraints) => Container(
width: constraints.widthConstraints().maxWidth,
height: constraints.heightConstraints().maxHeight,
color: Colors.yellow,
child: CustomPaint(painter: Thermometer()),
),
),
),
],
),
),
),
);
}
}
class Thermometer extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.brown
..style = PaintingStyle.stroke
..style = PaintingStyle.fill
..strokeWidth = 4;
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(0, -60, 40, 290), Radius.circular(20)),
paint,
);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

Get scroll distance each time user scroll a ListView

Using the scrollListener and ScrollController, how can I get the scroll distance from start to the end of the scrolling each time the user scroll?
ScrollController has a property called offset which will give you the current offset.
A working example follows
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController controller = ScrollController();
double initialPosition = 0.0;
double endPosition = 0.0;
double distance = 0.0;
#override
void initState() {
super.initState();
controller = ScrollController();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: NotificationListener(
onNotification: (notif) {
if(notif is ScrollStartNotification) {
initialPosition = controller.offset;
} else if(notif is ScrollEndNotification) {
endPosition = controller.offset;
distance = endPosition - initialPosition;
print(distance);
}
return true;
},
child: ListView(
controller: controller,
children: <Widget>[
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
color: Colors.red,
),
],
),),
);
}
}
UPDATE: Added code which helps in detecting start and end scroll.