Flutter - How to insert the ad in every nth row (every 4th row) in listview.separated - flutter

I am using Listview.separated and I am using google_mobile_ads as the package to integrate the ads. I followed the example here but dint get the exact what I needed.
I called the banner ad in separatorBuilder but that either gives the divider or the ad after every nth row.
I need insert the after every 4th row in the listview.separated.
ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
controller: _scrollController,
itemCount: articleslist.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == articleslist.length) {
_loading = true;
return Center(
child: Row(
children: [
Container(
padding: EdgeInsets.all(5),
child: CircularProgressIndicator(
color: Colors.deepOrange[800],
),
),
SizedBox(
width: 15,
),
Text(
'Articles are being loaded...',
style: TextStyle(color: Colors.deepOrange[800]),
)
],
),
);
} else {
Text(
'No data to load',
style: TextStyle(color: Colors.deepOrange[800]),
);
}
if (articleslist.length == 0) {
return Container(
child: Center(
child: Text('Loading...',
style: TextStyle(color: Colors.deepOrange))));
} else {
var imgUrl = articleslist[index].img.toString();
imgUrl = BaseUrl + imgUrl.toString();
var title = articleslist[index].title;
title = title.replaceAll(RegExp(r'<[^>]*>'), '');
var body = articleslist[index].body;
body = body.replaceAll(RegExp(r'<[^>]*>'), '');
return InkWell(
onTap: () {
print('Tapped : ${articleslist[index].nid}');
print(index);
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => DetailPage(
articleslist[index].title,
articleslist[index].img,
articleslist[index].nid,
articleslist[index].uid,
articleslist[index].created,
)));
},
child: Container(
padding: EdgeInsets.fromLTRB(8.0, 6.0, 8.0, 0.0),
child: Row(
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 120,
height: 75,
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: imgUrl == 'No img'
? Image.asset('images/placeholder.png',
height: 220, fit: BoxFit.cover)
: FadeInImage.assetNetwork(
placeholder: 'images/placeholder.png',
image: imgUrl,
height: 220,
fit: BoxFit.cover,
),
),
),
const SizedBox(
width: 20,
),
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: TextStyle(
color: Colors.black, fontSize: 16),
),
const SizedBox(
height: 10,
),
Text(
'author : $uid',
style: TextStyle(
fontSize: 10,
),
),
const SizedBox(
height: 5,
),
Text(
created,
style: TextStyle(
fontSize: 10,
),
)
],
),
),
],
),
),
);
}
},
separatorBuilder: (context, index) => Divider(),
),

You can add a item nth place using ListView.separated and '%' operator.
You just change from number '4' after '%' operator to what you want to add to nth place.
...
if ((index + 1) % 4 == 0) {
...
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> {
FocusNode focusNode = FocusNode();
#override
void initState() {
super.initState();
focusNode.addListener(() {
print('1: ${focusNode.hasFocus}');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _buildBody(),
);
}
Widget _buildBody() {
return ListView.separated(
itemCount: 20,
separatorBuilder: (context, index) {
if ((index + 1) % 4 == 0) {
return Container(
height: 100,
color: Colors.yellow,
child: Text('it is ads'),
);
} else {
return Container();
}
},
itemBuilder: (context, index) {
return Container(
height: 100,
color: Colors.blue,
child: Text('item index: $index'),
);
},
);
}
}

Related

convert listview to animatedlistview

I have created basic todo app Everything is going well but while deleting or converting to completed(clicked on checkbox) it removes instantly.. I want animated so that It took time and user can see its checked or deleted
I have done all code but now don't know how to replace and where part should be corrected to convert into AnimatedList...
I want to have ur suggestion,
for how to convert to animatedList and is there any simple way instead animatedList bcz I have to do many changes in converting list view to animated list
class TodoListWidget extends StatelessWidget {
const TodoListWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final provider = Provider.of<TodoProvider>(context);
final todos = provider.todos;
return todos.length == 0
? Center(
child: Text('No Todos'),
)
: ListView.separated(
//physics: BouncingScrollPhysics(),
padding: EdgeInsets.all(10),
separatorBuilder: (context, index) {
return Container(
height: 9,
);
},
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return TodoWidget(todo: todo);
},
);
}
}
here is my class todowidget
class TodoWidget extends StatelessWidget {
final Todo todo;
TodoWidget({required this.todo});
#override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Container(
color: todo.color,
padding: EdgeInsets.all(20),
child: Row(
children: [
todo.isdone==false?Checkbox(
activeColor: Colors.white,
checkColor: Colors.red,
value: todo.isdone,
onChanged: (value) {
final result= Provider.of<TodoProvider>(context,listen: false).toogletodo(todo);
}):IconButton(onPressed: (){
final result= Provider.of<TodoProvider>(context,listen: false).toogletodo(todo);
}, icon: Icon(Icons.refresh)),
SizedBox(
width: 20,
),
GestureDetector(
onTap: todo.isdone?null:(){
showDialog(
barrierDismissible: false,
context: context,
builder: (ctx)=> AddTodoDialogWidget(
title: todo.title,
description: todo.description,
isedit:true,
id: todo.id,
));
},
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(todo.title,style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16, color: Colors.black)),
SizedBox(height: 6,),
if (todo.description.isNotEmpty)
Container(
child: Text(
todo.description,
style: TextStyle(fontSize: 12, color: Colors.black),
),
),
],
),
),
),
Spacer(),
IconButton(
onPressed: () {
Provider.of<TodoProvider>(context,listen: false).deletetodo(todo);
},
icon: Icon(Icons.delete,color: Colors.red,)),
],
),
),
);
}
}

Flutter:How can i change the color of selected menu item from drawer

I am creating an app in flutter, I have got some issue in drawer. I want to change the color of the selected drawer item.Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
class _DrawerClassState extends State<DrawerClass> {
Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
List<String> menuStrings = [
'HOME',
'NOTIFICATIONS',
'PARTNERS',
'LOCATIONS',
'FEEDBACK',
'CONTACT US',
'AWARDS'
];
Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
List menuScreens = [
HomeScreen(),
Notifications(),
Partners(),
Locations(),
FeedbackScreen(),
const ContactUs(),
Awards()
];
Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
List<bool> isHighlighted = [false, false, false, false, true, false, false];
#override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.black,
),
child: Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
drawerTop("HI USER"),
ListView.builder(
shrinkWrap: true,
itemCount: menuScreens.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
for (int i = 0; i < isHighlighted.length; i++) {
setState(() {
if (index == i) {
isHighlighted[index] = true;
} else {
//the condition to change the highlighted item
isHighlighted[i] = false;
}
});
}
},
child: drawerItems(
context,
menuStrings[index],
menuScreens[index],
isHighlighted[index] ? Colors.amber : Colors.white,
),
);
},
),
],
),
),
);
}
}
Here is the method drawerItems() to build drawer items
drawerItems(BuildContext context, String title, path, Color color) {
return Padding(
padding: EdgeInsets.only(
top: 0.0, left: MediaQuery.of(context).size.width * 0.1),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: ((context) => path)));
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: TextStyle(
color: color,
fontFamily: "Raleway Reg",
fontSize: 23,
letterSpacing: 2),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: const Divider(
thickness: 1,
color: Colors.white,
height: 3,
),
),
]));
}
Update your drawerItems
drawerItems(BuildContext context, String title, path, Color color) {
return Container(
color: color,
padding: EdgeInsets.only(
top: 0.0, left: MediaQuery.of(context).size.width * 0.1),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: ((context) => path)));
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: TextStyle(
color: color,
fontFamily: "Raleway Reg",
fontSize: 23,
letterSpacing: 2),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: const Divider(
thickness: 1,
color: Colors.white,
height: 3,
),
),
]));
}
the root widget that is returned from the method, change it from Padding to Container and give it a color
I think it's a very complex solution to solve this simple task in Flutter.
I suggest my solution:
Publish it on my git:
https://github.com/igdmitrov/flutter-drawer
Create a new Abstract Page State:
abstract class MyPageState<T extends StatefulWidget> extends State {
List<Widget> drawerItems(BuildContext context) {
return menuItems
.map(
(item) => ListTile(
leading: const Icon(Icons.my_library_books),
title: Text(
item['menuName'] as String,
style: TextStyle(
color: isHighlighted[menuItems.toList().indexOf(item)]
? Colors.amber
: Colors.grey),
),
onTap: () {
isHighlighted = isHighlighted.map((mark) => false).toList();
isHighlighted[menuItems.toList().indexOf(item)] = true;
Navigator.of(context).push(MaterialPageRoute(
builder: ((context) => item['route'] as Widget)));
},
),
)
.toList();
}
}
Create drawer.dart file with code:
final menuItems = {
{'menuName': 'HOME', 'route': const HomeScreen()},
{'menuName': 'NOTIFICATIONS', 'route': const Notifications()},
};
List<bool> isHighlighted = [false, false];
And create pages:
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
MyPageState<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends MyPageState<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Main page'),
),
drawer: Drawer(
child: ListView(
children: [
const Text("HI USER"),
...drawerItems(context),
],
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'New app',
),
],
),
),
);
}
}
And Notifications page:
class Notifications extends StatefulWidget {
static String routeName = '/notifications';
const Notifications({Key? key}) : super(key: key);
#override
MyPageState<Notifications> createState() => _NotificationsState();
}
class _NotificationsState extends MyPageState<Notifications> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Notifications'),
),
drawer: Drawer(
child: ListView(
children: [
const Text("HI USER"),
...drawerItems(context),
],
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'Notifications page',
),
],
),
),
);
}
}

How to zoom an item of a list on mouse-over, keeping it always visible (Flutter on Web platform)

The problem is described like this.
In a web environment, I have to build a horizontal list of images (like in Netflix) which should increase the size of the element when the user positions the mouse cursor over them. To achieve this, I'm using a Stack (with clipBehavior equals to Clip.none) to render each item in the list, when I detect the mouse-over event I add a new Container (larger than the size of the original item) to draw an AnimatedContainer inside which will grow to fill it.
The animation works great, but the container gets positioned down to the next right item on the list, however, I need it above the item.
Here is the code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: 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({Key? key, required this.title}) : super(key: key);
final String title;
#override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
final double zoomTargetHeight = 320;
final double zoomTargetWidth = 500;
final double zoomOriginalHeight = 225;
final double zoomOriginalWidth = 400;
double _zoomHeight = 225;
double _zoomWidth = 400;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: [
Image.network("https://source.unsplash.com/random/1600x900?cars"),
Container(
color: Colors.black87,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 12,
),
const Text(
"List of items",
style: TextStyle(color: Colors.white),
),
const SizedBox(
height: 12,
),
SizedBox(
height: 235,
child: ListView.separated(
clipBehavior: Clip.none,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return buildCard(index);
},
separatorBuilder: (context, index) {
return const SizedBox(
width: 12,
);
},
itemCount: 10,
),
),
const SizedBox(
height: 200,
),
],
),
),
),
],
),
),
);
}
Map _showZoom = {};
Widget buildCard(int index) {
Stack stack = Stack(
clipBehavior: Clip.none,
children: [
MouseRegion(
onEnter: (event) {
setState(() {
_showZoom["$index"] = true;
});
},
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
Image.network(
"https://source.unsplash.com/random/400x225?sig=$index&cars"),
Container(
color: Colors.black.withAlpha(100),
height: zoomOriginalHeight,
width: zoomOriginalWidth,
),
],
),
),
),
if (_showZoom["$index"] != null && _showZoom["$index"]!)
Positioned(
left: (zoomOriginalWidth - zoomTargetWidth) / 2,
top: (zoomOriginalHeight - zoomTargetHeight) / 2,
child: MouseRegion(
onHover: (_) {
setState(() {
_zoomHeight = zoomTargetHeight;
_zoomWidth = zoomTargetWidth;
});
},
onExit: (event) {
setState(() {
_showZoom["$index"] = false;
_zoomHeight = zoomOriginalHeight;
_zoomWidth = zoomOriginalWidth;
});
},
child: SizedBox(
width: zoomTargetWidth,
height: zoomTargetHeight,
child: Center(
child: AnimatedContainer(
duration: const Duration(milliseconds: 400),
width: _zoomWidth,
height: _zoomHeight,
// color: Colors.green.withAlpha(100),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
image: NetworkImage(
"https://source.unsplash.com/random/400x225?sig=$index&cars"),
fit: BoxFit.cover,
),
),
),
),
),
),
),
],
);
return stack;
}
}
Remember flutter config --enable-web
I think this is precisely what you are looking for (Check also the live demo on DartPad):
The solution is:
Use an outer Stack that wraps the ListView;
Add another ListView in front of it in the Stack with the same number of items and same item sizes;
Then, ignore the pointer-events with IgnorePointer on this new ListView so the back one will receive the scroll/tap/click events;
Synchronize the scroll between the back ListView and the front one by listening to scroll events with NotificationListener<ScrollNotification>;
Here's the code
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: 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({Key? key, required this.title}) : super(key: key);
final String title;
#override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
final double zoomTargetHeight = 320;
final double zoomTargetWidth = 500;
final double zoomOriginalHeight = 225;
final double zoomOriginalWidth = 400;
late final ScrollController _controllerBack;
late final ScrollController _controllerFront;
#override
void initState() {
super.initState();
_controllerBack = ScrollController();
_controllerFront = ScrollController();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Image.network("https://source.unsplash.com/random/1600x900?cars"),
Container(
color: Colors.black87,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 12,
),
const Text(
"List of items",
style: TextStyle(color: Colors.white),
),
const SizedBox(
height: 12,
),
SizedBox(
height: 225,
child: NotificationListener<ScrollNotification>(
onNotification: (notification) {
_controllerFront.jumpTo(_controllerBack.offset);
return true;
},
child: Stack(
clipBehavior: Clip.none,
children: [
ListView.separated(
controller: _controllerBack,
clipBehavior: Clip.none,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return buildBackCard(index);
},
separatorBuilder: (context, index) {
return const SizedBox(
width: 12,
);
},
itemCount: 10,
),
IgnorePointer(
child: ListView.separated(
controller: _controllerFront,
clipBehavior: Clip.none,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return buildFrontCard(index);
},
separatorBuilder: (context, index) {
return const SizedBox(
width: 12,
);
},
itemCount: 10,
),
),
],
),
),
),
const SizedBox(
height: 200,
),
],
),
),
),
],
),
),
);
}
final Map _showZoom = {};
Widget buildBackCard(int index) {
return MouseRegion(
onEnter: (event) {
setState(() {
_showZoom["$index"] = true;
});
},
onExit: (event) {
setState(() {
_showZoom["$index"] = false;
});
},
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
Image.network(
"https://source.unsplash.com/random/400x225?sig=$index&cars",
),
Container(
color: Colors.black.withAlpha(100),
height: zoomOriginalHeight,
width: zoomOriginalWidth,
),
],
),
),
);
}
Widget buildFrontCard(int index) {
Widget child;
double scale;
if (_showZoom["$index"] == null || !_showZoom["$index"]!) {
scale = 1;
child = SizedBox(
height: zoomOriginalHeight,
width: zoomOriginalWidth,
);
} else {
scale = zoomTargetWidth / zoomOriginalWidth;
child = Stack(
clipBehavior: Clip.none,
children: [
Container(
height: zoomOriginalHeight,
width: zoomOriginalWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
image: NetworkImage(
"https://source.unsplash.com/random/400x225?sig=$index&cars"),
fit: BoxFit.cover,
),
),
),
],
);
}
return AnimatedScale(
duration: const Duration(milliseconds: 400),
scale: scale,
child: child,
);
}
}
I'd do something different. Instead of Stacking the zoomed-out and zoomed-in images it could be just one image with a AnimatedScale to do the transitions.
Check the code below:
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
AnimatedScale(
duration: const Duration(milliseconds: 400),
scale: _showZoom["$index"] == true
? zoomTargetWidth / zoomOriginalWidth
: 1,
child: Image.network(
"https://source.unsplash.com/random/400x225?sig=$index&cars"),
),
if (_showZoom["$index"] == null || _showZoom["$index"] == false)
Container(
color: Colors.black.withAlpha(100),
height: zoomOriginalHeight,
width: zoomOriginalWidth,
),
],
),
),
Check out the screenshot and the live demo on DartPad:
All source
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: 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({Key? key, required this.title}) : super(key: key);
final String title;
#override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
final double zoomTargetHeight = 320;
final double zoomTargetWidth = 500;
final double zoomOriginalHeight = 225;
final double zoomOriginalWidth = 400;
double _zoomHeight = 225;
double _zoomWidth = 400;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Image.network("https://source.unsplash.com/random/1600x900?cars"),
Container(
color: Colors.black87,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 12,
),
const Text(
"List of items",
style: TextStyle(color: Colors.white),
),
const SizedBox(
height: 12,
),
SizedBox(
height: 235,
child: ListView.separated(
clipBehavior: Clip.none,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return buildCard(index);
},
separatorBuilder: (context, index) {
return const SizedBox(
width: 12,
);
},
itemCount: 10,
),
),
const SizedBox(
height: 200,
),
],
),
),
),
],
),
),
);
}
Map _showZoom = {};
Widget buildCard(int index) {
Stack stack = Stack(
clipBehavior: Clip.none,
children: [
MouseRegion(
onEnter: (event) {
setState(() {
_showZoom["$index"] = true;
});
},
onExit: (event) {
setState(() {
_showZoom["$index"] = false;
});
},
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
AnimatedScale(
duration: const Duration(milliseconds: 400),
scale: _showZoom["$index"] == true
? zoomTargetWidth / zoomOriginalWidth
: 1,
child: Image.network(
"https://source.unsplash.com/random/400x225?sig=$index&cars"),
),
if (_showZoom["$index"] == null || _showZoom["$index"] == false)
Container(
color: Colors.black.withAlpha(100),
height: zoomOriginalHeight,
width: zoomOriginalWidth,
),
],
),
),
),
],
);
return stack;
}
}

The class 'SimpleFoldingCell' doesn't have a default constructor

https://github.com/flutter-devs/flutter_folding_cell_demo/blob/master/lib/demo_screen.dart
I'm trying to follow the code in the link above.
But in the SimpleFoldingCell part, an error named 'The class 'SimpleFoldingCell' doesn't have a default constructor.' occurs.
Could
Is there a way to resolve this error in Dart?
class Notific extends StatefulWidget{
#override
_State createState() => _State();
}
class _State extends State<Notific>{
late List<TechnologyModel> _technologyList;
#override
void initState() {
super.initState();
_technologyList = [
TechnologyModel(title: "Application Development",),
TechnologyModel(title: "Research & Development",),
TechnologyModel(title: "Big Data & Analytics",),
TechnologyModel(title: "Support Services",),
TechnologyModel(title: "QA & Software Testing",),
];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.pink[200],
title: Text("Folding Cell Demo",
style: TextStyle(color: Colors.white),),
),
body: Container(
child: ListView.builder(
itemCount: _technologyList.length,
itemBuilder: (context, index) {
return SimpleFoldingCell(
frontWidget: _buildFrontWidget(index),
innerTopWidget: _buildInnerWidget(index),
innerBottomWidget: _buildInnerBottomWidget(),
cellSize: Size(MediaQuery.of(context).size.width, 125),
padding: EdgeInsets.all(15),
animationDuration: Duration(milliseconds: 200),
borderRadius: 10,
onOpen: () => print('$index cell opened'),
onClose: () => print('$index cell closed'),
);
},
),
),
);
}
Widget _buildFrontWidget(int index) {
return Builder(
builder: (BuildContext context) {
return Container(
color: Colors.cyan[100],
alignment: Alignment.bottomCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Aeologic Technology",
style: TextStyle(
fontSize:20.0,
color: Colors.black,
),
),
SizedBox(height: 10,),
FlatButton(
onPressed: () {
final foldingCellState = context
.findAncestorStateOfType<SimpleFoldingCellState>();
foldingCellState?.toggleFold();
},
child: Text(
"OPEN",
),
textColor: Colors.white,
color: Colors.indigoAccent[100],
splashColor: Colors.white.withOpacity(0.5),
),
],
),
);
},
);
}
Widget _buildInnerBottomWidget() {
return Builder(
builder: (context) {
return Container(
color: Colors.blueGrey[50],
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 10),
child: FlatButton(
onPressed: () {
final foldingCellState = context
.findAncestorStateOfType<SimpleFoldingCellState>();
foldingCellState?.toggleFold();
},
child: Text(
"Close",
),
textColor: Colors.white,
color: Colors.redAccent[100],
splashColor: Colors.white.withOpacity(0.5),
),
),
);
}
);
}
Widget _buildInnerWidget(int index) {
return Builder(
builder: (context) {
return Container(
color: Colors.pink[100],
padding: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.center,
child: Text(
_technologyList[index].title,
style: TextStyle(
fontSize:20.0,
color: Colors.black,
),
),
),
);
},
);
}
}
class TechnologyModel {
String title;
TechnologyModel({
required this.title,
});
}
For some reason they've created only a named constructor.
return SimpleFoldingCell.create(
frontWidget: _buildFrontWidget(index),
innerWidget: _buildInnerWidget(index),
// innerTopWidget: _buildInnerWidget(index),
// innerBottomWidget: _buildInnerBottomWidget(),
cellSize: Size(MediaQuery.of(context).size.width, 125),
padding: EdgeInsets.all(15),
animationDuration: Duration(milliseconds: 200),
borderRadius: 10,
onOpen: () => print('$index cell opened'),
onClose: () => print('$index cell closed'),
);
It looks like the demo you're looking at is a bit outdated, since some of those properties don't exist anymore (see commented code).

Extend multiple classes Flutter

I have a bottom navigation bar that redirects me to this classes:
final List pages = [
Home(),
Busca(),
Pedidos(),
Perfil(),
];
But i have multiple classes in each of these pages and it only shows the one it is being redirect to.
How can i show all the classes that i have in each file?
That is my file that represents the "Busca" page:
class Busca extends StatefulWidget {
#override
_BuscaState createState() => _BuscaState();
}
class _BuscaState extends State<Busca> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SearchBar<Post>(
searchBarStyle: SearchBarStyle(
backgroundColor: Colors.tealAccent.withOpacity(0.7),
padding: EdgeInsets.all(5),
borderRadius: BorderRadius.circular(10),),
onSearch: search,
loader: Center(
child: Text("Buscando..."),
),
cancellationText: Text("Cancelar"),
crossAxisCount: 2,
indexedScaledTileBuilder: (int index) => ScaledTile.count(
index % 3 == 0 ? 2 : 2,
1,
),
hintText: "Busque Pratos ou Restaurantes",
hintStyle: TextStyle(
color: Colors.grey,
),
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
iconActiveColor: Colors.black,
mainAxisSpacing: 20,
crossAxisSpacing: 20,
onItemFound: (Post post, int index) {
return Container(
color: Colors.tealAccent,
child: ListTile(
title: Text(post.title),
isThreeLine: true,
subtitle: Text(post.description),
)
);
},
),
),
),
);
}
}
class Categorias extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
// Row 1
Row(
children: <Widget>[
Container(
color: Colors.blue, height: 40, width: 40, child: Text('1')),
Container(
color: Colors.blue, height: 40, width: 40, child: Text('2')),
Container(
color: Colors.red, height: 40, width: 40, child: Text('3')),
],
),
]
);
}
}
When i click the button that redirects me to "Busca" the class "Categorias" does not appear below it.
How can i make it appear as well by just redirecting to "Busca"?
You can copy paste run full code below
You can use Column and Expaneded flex
code snippet
Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Expanded(
flex: 1,
child: SearchBar<Post>(
...
),
Expanded(flex: 1, child: Categorias())
],
working demo
full code
import 'dart:math';
import 'package:flappy_search_bar/scaled_tile.dart';
import 'package:flappy_search_bar/search_bar_style.dart';
import 'package:flutter/material.dart';
import 'package:flappy_search_bar/flappy_search_bar.dart';
class Post {
final String title;
final String body;
final String description;
Post(this.title, this.body, this.description);
}
class Busca extends StatefulWidget {
#override
_BuscaState createState() => _BuscaState();
}
class _BuscaState extends State<Busca> {
bool isReplay = false;
Future<List<Post>> search(String text) async {
await Future.delayed(Duration(seconds: text.length == 4 ? 10 : 1));
if (isReplay) return [Post("Replaying !", "Replaying body", "desc")];
if (text.length == 5) throw Error();
if (text.length == 6) return [];
List<Post> posts = [];
var random = new Random();
for (int i = 0; i < 10; i++) {
posts.add(Post(
"$text $i", "body random number : ${random.nextInt(100)}", "desc"));
}
return posts;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Expanded(
flex: 1,
child: SearchBar<Post>(
searchBarStyle: SearchBarStyle(
backgroundColor: Colors.tealAccent.withOpacity(0.7),
padding: EdgeInsets.all(5),
borderRadius: BorderRadius.circular(10),
),
onSearch: search,
loader: Center(
child: Text("Buscando..."),
),
//cancellationText: Text("Cancelar"),
crossAxisCount: 2,
indexedScaledTileBuilder: (int index) => ScaledTile.count(
index % 3 == 0 ? 2 : 2,
1,
),
hintText: "Busque Pratos ou Restaurantes",
hintStyle: TextStyle(
color: Colors.grey,
),
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
iconActiveColor: Colors.black,
mainAxisSpacing: 20,
crossAxisSpacing: 20,
onItemFound: (Post post, int index) {
return Container(
color: Colors.tealAccent,
child: ListTile(
title: Text(post.title),
isThreeLine: true,
subtitle: Text(post.description),
));
},
),
),
Expanded(flex: 1, child: Categorias())
],
),
),
),
);
}
}
class Categorias extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
// Row 1
Row(
children: <Widget>[
Container(
color: Colors.blue, height: 40, width: 40, child: Text('1')),
Container(
color: Colors.blue, height: 40, width: 40, child: Text('2')),
Container(
color: Colors.red, height: 40, width: 40, child: Text('3')),
],
),
]);
}
}
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: Busca(),
);
}
}
call Categoria within the Buca class. How you do this will depend on which type of layout you are aiming for. What you could go is place everything you have in Buca within the children of a column, the next child within children could be categoria.
This Would effectively allow whatever you have in Categoria to be rendered right after Buca.
I don't want to confuse you since you are a beginner, all you need to do is find the right widget container that can hold multiple widgets ie. something with the children attribute. Column, ListView, GridView or Row should do Just fine.
body: Column(children:[SafeArea........
, Categorias()
]'''