ListView in flutter with shuffle animation - flutter

So in my flutter screen I have these tiles that is each tile has a letter in it. My plan there that these tiles must be expected to be shuffled when the button is click. Currently, I just have little knowledge in regarding with Flutter animation. I need your help guys.
Example of shuffle animation
PS: this picture is not mine. I just want to upload this so then you have idea what does shuffle animation do in my tiles.
PS:
Currently I have this code:
GridView.count(
crossAxisCount: 6,
crossAxisSpacing: 4.0,
mainAxisSpacing: 8.0,
padding: const EdgeInsets.all(8.0),
children: List.generate(
12,
(index) {
return Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline5,
),
),
);
},
),
);

You can try this (DartPad) :
import 'package:flutter/material.dart';
void main() async => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final String word = "TRIPLE";
final double size = 170;
final double space = 10;
late final List<Color> colors = Colors.primaries
.take(word.length)
.map((MaterialColor m) => m.shade800)
.toList();
late final int containerNumber = word.length;
late final List<Rect> positions = List.generate(
containerNumber,
(index) => getRectangle(index, containerNumber, size)
);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Material App Bar'),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 50,),
ElevatedButton(
onPressed: shuffle,
child: const Text("Shuffle")
),
const SizedBox(height: 50,),
SizedBox(
height: containerNumber ~/3 * (size+space) - space,
width: 3 * (size+space) - space,
child: Stack(
fit: StackFit.loose,
alignment: Alignment.center,
children: List.generate(containerNumber, (index) {
return AnimatedPositioned.fromRect(
rect: positions[index],
duration: const Duration(milliseconds: 500),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: colors[index],
),
width: size,
height: size,
child: Text(
word[index],
style: const TextStyle(
fontSize: 60,
fontWeight: FontWeight.w900,
color: Colors.white
),
),
),
);
}),
)
),
]
),
)
)
),
);
}
Rect getRectangle(int index, int length, double size) {
return
Offset(index % 3 * (size + space), index ~/3 * (size + space))
& Size.square(size);
}
void shuffle() {
setState(() {
positions.shuffle();
});
}
}

Related

Why isn't the BottomAppBar showing up?

I'm following this tutorial on youtube (https://www.youtube.com/watch?v=MW-KVmnXuiE) and at 01:27, when I tried to reload my emulator, the BottomAppBar didn't show up. There weren't any errors occurred though.
This is my main.dart file
import 'package:flutter/material.dart';
import 'package:secondlife_mobile/screens/home.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Perspective PageView',
theme: ThemeData(
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomAppBar(
child: Row(
children: [
IconButton(onPressed: () {}, icon: const Icon(Icons.home)),
IconButton(onPressed: () {}, icon: const Icon(Icons.home)),
],
),
),
);
}
}
And this is my home.dart file
import 'package:flutter/material.dart';
import 'package:secondlife_mobile/PageViewHolder.dart';
import 'package:provider/provider.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final PageStorageBucket bucket = PageStorageBucket();
late PageViewHolder holder;
late PageController _controller;
double fraction =
0.57; // By using this fraction, we're telling the PageView to show the 50% of the previous and the next page area along with the main page
#override
void initState() {
super.initState();
holder = PageViewHolder(value: 2.0);
_controller = PageController(initialPage: 2, viewportFraction: fraction);
_controller.addListener(() {
holder.setValue(_controller.page);
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('AppBar'),
leading: IconButton(
onPressed: () {},
icon: const Icon(Icons.search_outlined),
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_vert),
),
],
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 92.5,
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Text(
'Playlist for you',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w400,
),
),
),
const SizedBox(height: 35),
Container(
child: Center(
child: AspectRatio(
aspectRatio: 1,
child: ChangeNotifierProvider<PageViewHolder>.value(
value: holder,
child: PageView.builder(
controller: _controller,
itemCount: 4,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return MyPage(
number: index.toDouble(),
fraction: fraction,
);
}),
),
),
),
),
const SizedBox(height: 2.0),
////Your Playlist of the week text
const Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Text(
'Playlist of the week',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
),
),
),
],
),
),
),
),
);
}
}
class MyPage extends StatelessWidget {
final number;
final double? fraction;
const MyPage({super.key, this.number, this.fraction});
#override
Widget build(BuildContext context) {
double? value = Provider.of<PageViewHolder>(context).value;
double diff = (number - value);
// diff is negative = left page
// diff is 0 = current page
// diff is positive = next page
//Matrix for Elements
final Matrix4 pvMatrix = Matrix4.identity()
..setEntry(3, 2, 1 / 0.9) //Increasing Scale by 90%
..setEntry(1, 1, fraction!) //Changing Scale Along Y Axis
..setEntry(3, 0, 0.004 * -diff); //Changing Perspective Along X Axis
final Matrix4 shadowMatrix = Matrix4.identity()
..setEntry(3, 3, 1 / 1.6) //Increasing Scale by 60%
..setEntry(3, 1, -0.004) //Changing Scale Along Y Axis
..setEntry(3, 0, 0.002 * diff) //Changing Perspective along X Axis
..rotateX(1.309); //Rotating Shadow along X Axis
return Stack(
fit: StackFit.expand,
alignment: FractionalOffset.center,
children: [
Transform.translate(
offset: const Offset(0.0, -47.5),
child: Transform(
transform: pvMatrix,
alignment: FractionalOffset.center,
child: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
blurRadius: 11.0,
spreadRadius: 4.0,
offset: const Offset(
13.0, 35.0), // shadow direction: bottom right
)
]),
child: Image.asset(
"assets/images/image_${number.toInt() + 1}.jpg",
fit: BoxFit.fill),
),
),
),
],
);
}
}
And this is how my emulator looked like when I reloaded it.
As you can see, the BottomAppBar isn't showing up.
As far as I read your code, the HomePage class didn't get called.
Update the Scaffold inside your MyHomePage class with the BottomAppBar from your HomePage class.
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
bottomNavigationBar: BottomAppBar(
child: Row(
children: [
IconButton(onPressed: () {}, icon: const Icon(Icons.home)),
IconButton(onPressed: () {}, icon: const Icon(Icons.home)),
],
),
),
appBar: AppBar(
centerTitle: true,
title: const Text('AppBar'),
leading: IconButton(
onPressed: () {},
icon: const Icon(Icons.search_outlined),
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_vert),
),
],
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 92.5,
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Text(
'Playlist for you',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w400,
),
),
),
const SizedBox(height: 35),
Container(
child: Center(
child: AspectRatio(
aspectRatio: 1,
child: ChangeNotifierProvider<PageViewHolder>.value(
value: holder,
child: PageView.builder(
controller: _controller,
itemCount: 4,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return MyPage(
number: index.toDouble(),
fraction: fraction,
);
}),
),
),
),
),
const SizedBox(height: 2.0),
////Your Playlist of the week text
const Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Text(
'Playlist of the week',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
),
),
),
],
),
),
),
),
);
}
}
It's because your are not using the widget HomePage anywhere.
You can add the MyHomePage widget as the body of the scaffold widget in the HomePage, like so:
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomAppBar(
child: Row(
children: [
IconButton(onPressed: () {}, icon: const Icon(Icons.home)),
IconButton(onPressed: () {}, icon: const Icon(Icons.home)),
],
),
),
body: MyHomePage(),
);
}
}
And then your App widget would look like:
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Perspective PageView',
theme: ThemeData(
useMaterial3: true,
),
home: const HomePage(),
);
}
}

How to build an on tap Expandable container

So I was trying to build a user id page for my flutter app where you tap on a container and the containers height is increased and a different set of data is shown. On expanded I also wanted to add a scrollable tabview and that's second part of the problem.
the expected ui looks like thishttps://i.stack.imgur.com/62sro.gif.
I have tried Expanded and expansion tile, Can't quite achieve the output
Is there any other method to achieve this?
Welcome #Anand Pillai,
First add this line to your pubspec.yaml expandable: ^5.0.1
try this code
import 'package:expandable/expandable.dart';
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(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late PageController _pageController;
final ExpandableController _controller = ExpandableController();
int activePage = 1;
int _counter = 0;
List<String> images = [
"https://images.pexels.com/photos/14686142/pexels-photo-14686142.jpeg",
"https://wallpaperaccess.com/full/2637581.jpg",
"https://uhdwallpapers.org/uploads/converted/20/01/14/the-mandalorian-5k-1920x1080_477555-mm-90.jpg"
];
List<Widget> indicators(imagesLength, currentIndex) {
return List<Widget>.generate(imagesLength, (index) {
return Container(
margin: const EdgeInsets.all(3),
width: 10,
height: 10,
decoration: BoxDecoration(
color: currentIndex == index ? Colors.white : Colors.blueGrey,
shape: BoxShape.circle),
);
});
}
AnimatedContainer slider(images, pagePosition, active) {
// double margin = active ? 10 : 20;
return AnimatedContainer(
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubic,
// margin: EdgeInsets.all(margin),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(images[pagePosition]),
fit: BoxFit.cover,
)),
);
}
#override
void initState() {
super.initState();
_pageController = PageController();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Stack(
alignment: Alignment.center,
children: [imageSlider(), expandedWidget(context)],
),
),
],
));
}
Positioned expandedWidget(BuildContext context) {
return Positioned.fill(
bottom: _controller.expanded ? 0 : 60,
left: 0,
right: 0,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_controller.expanded
? const SizedBox.shrink()
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: indicators(images.length, activePage)),
ExpandableNotifier(
child: AnimatedContainer(
height: _controller.expanded ? 400 : 110.0,
width: double.infinity,
alignment: Alignment.bottomCenter,
padding: const EdgeInsets.all(15.0),
margin: _controller.expanded
? EdgeInsets.zero
: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 255, 79, 77).withOpacity(0.8),
borderRadius: _controller.expanded
? const BorderRadius.only(
topRight: Radius.circular(15),
topLeft: Radius.circular(15),
)
: BorderRadius.circular(15.0),
),
duration: const Duration(milliseconds: 500),
child: Column(
children: <Widget>[
ScrollOnExpand(
scrollOnExpand: true,
scrollOnCollapse: false,
child: ExpandablePanel(
controller: _controller
..addListener(() {
setState(() {});
}),
theme: const ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
tapBodyToCollapse: true,
iconColor: Colors.white,
),
header: Padding(
padding: const EdgeInsets.all(10),
child: Text(
"ExpandablePanel",
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.white),
)),
collapsed: const Text(
"loremIpsum",
style: TextStyle(color: Colors.white),
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
expanded: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
for (var _ in Iterable.generate(5))
const Padding(
padding: EdgeInsets.only(bottom: 10),
child: Text(
"loremIpsum",
style: TextStyle(color: Colors.white),
softWrap: true,
overflow: TextOverflow.fade,
)),
],
),
builder: (_, collapsed, expanded) {
return Padding(
padding: const EdgeInsets.only(
left: 10, right: 10, bottom: 10),
child: Expandable(
collapsed: collapsed,
expanded: expanded,
theme: const ExpandableThemeData(crossFadePoint: 0),
),
);
},
),
),
],
),
)),
],
));
}
PageView imageSlider() {
return PageView.builder(
itemCount: images.length,
physics: _controller.expanded
? const NeverScrollableScrollPhysics()
: ScrollPhysics(),
padEnds: false,
controller: _pageController,
onPageChanged: (page) {
setState(() {
activePage = page;
});
},
itemBuilder: (context, pagePosition) {
bool active = pagePosition == activePage;
return slider(images, pagePosition, active);
});
}
}
class _MyHomePageState extends State<MyHomePage> {
double _margin = 30, _height = 100, _width = 300;
final Text _widget1 = const Text('This is my Foo');
final Text _widget2 = const Text('This is Bar');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: GestureDetector(
// When the child is tapped, set state is called.
onTap: () {
setState(() {
_margin = _margin == 30 ? 0 : 30;
_height = _height == 100 ? 300 : 100;
_width = _width == 300 ? MediaQuery.of(context).size.width : 300;
});
},
// The custom button
child: Align(
alignment: Alignment.bottomCenter,
child: AnimatedContainer(
width: _width,
height: _height,
curve: Curves.easeInExpo,
margin: EdgeInsets.fromLTRB(_margin, 0, _margin, _margin),
duration: Duration(milliseconds: 250),
padding: const EdgeInsets.all(0),
decoration: BoxDecoration(
color: Colors.lightBlue,
borderRadius: BorderRadius.circular(8.0),
),
child: _margin == 30 ? _widget1 : _widget2,
),
),
)),
);
}
}
Simple logic is to animate the container when tapped and change the widget in it. On tap it calls setsate that sets the height, width, margin and child of the container.

How to expand list items without affecting other items. (flutter)

I want to create the Netflix home page in flutter, and I'm stuck while creating this hover state.
I have created two base widgets. One for the number plus the thumbnail and the other one for the expanded view when the widget is hovered. Then I put them in a stack with an Inkwell where the onHover changes the state to show the expanded widget.
When I hover on the widget, it does switch between the normal state an expanded state, the problem comes when I try to put a list of these widgets together.
When using row (or ListView) to put them together, after hovering, the expanded widget makes the other widgets move. (which is not the wanted behaviour, I want them to overlap)
When I use it with stack, the widgets do overlap but now it isn't scrollable anymore.
I have added the link to the repo for anyone that wants to clone it and try running it themselves, I'm running it on flutter web.
https://github.com/Advait1306/netflix-flutter
Widget with thumbnail and number:
class TopListItem extends StatelessWidget {
final int index;
const TopListItem({Key? key, required this.index}) : super(key: key);
#override
Widget build(BuildContext context) {
const double height = 250;
return SizedBox(
height: height,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset("assets/numbers/$index.svg",
fit: BoxFit.fitHeight, height: height),
Transform.translate(
offset: const Offset(-30, 0),
child: Image.asset("assets/thumbnails/thumb1.jpg"))
],
),
);
}
}
Expanded view widget:
import 'package:flutter/material.dart';
class HoverMovieTrailer extends StatelessWidget {
const HoverMovieTrailer({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const textTheme = TextStyle(color: Colors.white);
return SizedBox(
width: 400,
height: 400,
child: Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: const Color(0xFF242424)),
child: Column(
children: [
Image.asset("assets/backgrounds/background1.jpg"),
const SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 18),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: const [
RoundIconButton(icon: Icons.play_arrow_outlined),
SizedBox(width: 5),
RoundIconButton(icon: Icons.add_outlined),
SizedBox(width: 5),
RoundIconButton(icon: Icons.thumb_up_alt_outlined),
SizedBox(width: 5),
],
),
Row(
children: const [
RoundIconButton(icon: Icons.keyboard_arrow_down_outlined),
],
),
],
),
),
const SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 18),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text(
"98% Match",
style: TextStyle(
color: Colors.green,
fontWeight: FontWeight.bold
),
),
const SizedBox(width: 5),
Container(
padding: const EdgeInsets.all(1),
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 1)
),
child: const Text(
"18+",
style: textTheme,
),
),
const SizedBox(width: 5),
const Text(
"4 Seasons",
style: textTheme,
),
const SizedBox(width: 5),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 1)
),
child: const Text(
"HD",
style: textTheme,
),
)
],
),
),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.all(18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text(
"Captivating",
style: textTheme,
),
const SizedBox(width: 5),
Container(
width: 5,
height: 5,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white54
),
),
const SizedBox(width: 5),
const Text(
"Exciting",
style: textTheme,
),
const SizedBox(width: 5),
Container(
width: 5,
height: 5,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white54
),
),
const SizedBox(width: 5),
const Text(
"Docuseries",
style: textTheme,
),
],
),
),
],
),
),
);
}
}
class RoundIconButton extends StatelessWidget {
final IconData icon;
const RoundIconButton({Key? key, required this.icon}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent,
border: Border.all(width: 2, color: Colors.white)),
margin: const EdgeInsets.all(1),
child: IconButton(
onPressed: () {},
icon: Icon(icon),
color: Colors.white,
),
);
}
}
Combining the widgets in the single widget:
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:netflix_flutter/widgets/hover_movie_trailer.dart';
import 'package:netflix_flutter/widgets/top_list_item.dart';
class TopListItemWithHover extends StatefulWidget {
const TopListItemWithHover({Key? key}) : super(key: key);
#override
State<TopListItemWithHover> createState() => _TopListItemWithHoverState();
}
class _TopListItemWithHoverState extends State<TopListItemWithHover> {
bool hover = false;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: (){},
onHover: (value){
log("Hover value: $value");
setState(() {
hover = value;
});
},
child: Stack(
clipBehavior: Clip.none,
children: [
TopListItem(index: 1),
if(hover) HoverMovieTrailer(),
],
),
);
}
}
Lists:
import 'package:flutter/material.dart';
import 'package:netflix_flutter/widgets/hover_movie_trailer.dart';
import 'package:netflix_flutter/widgets/top_list_item.dart';
import 'package:netflix_flutter/widgets/top_list_item_with_hover.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<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
height: 400,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
clipBehavior: Clip.none,
itemCount: 8,
itemBuilder: (context, index) {
return TopListItemWithHover();
},
),
),
),
const SizedBox(height: 50),
SingleChildScrollView(
child: SizedBox(
height: 400,
child: Stack(
fit: StackFit.passthrough,
children: [
for (var i = 10; i >= 0; i--)
Positioned(
left: (i) * 300,
child: TopListItemWithHover(),
)
],
),
),
)
],
),
);
}
}
So finally found the solution to this problem, the way to move forward is to use a stack in SingleChildScrollView.
A mistake that I made is, I did not set the SingleChildScrollView's direction to horizontal. So I added that.
And then one more addition that's needed is -- A empty sized box which has the width of sum of all the items in the stack.
Stack(
clipBehavior: Clip.none,
children: [
const SizedBox(
width: 300*10,
),
for (var i = 10; i >= 0; i--)
Positioned(
left: (i) * 300,
child: TopListItemWithHover(),
)
],
)
This finally expanded the stack to the required width and then made is scrollable also.

How can I change the state not using button in flutter and problem with flutter sensor

Can I ask more? if I want to create an application like heads up what sensor I need to use Gyroscope right.
I need to use a sensor in this code so what I going to add to this code. please help me to solve this problem I'm a Newbie of flutter So I need to use a ternary operator?
flutter can set state inside the Container or padding or anything?
import 'package:flutter/material.dart';
import 'package:sensors/sensors.dart';
class GameGuessWord extends StatefulWidget {
#override
_GameGuessWordState createState() => _GameGuessWordState();
}
class _GameGuessWordState extends State<GameGuessWord> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.indigo[900],
body: Column(
// mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: (MediaQuery.of(context).size.height) / 2 - 60),
child: Text(
'FootBall',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 100,
color: Colors.white,
),
),
),
Container(
margin:
EdgeInsets.only(top: (MediaQuery.of(context).size.height / 8)),
padding: EdgeInsets.all(10),
child: Center(
child: Container(
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.amber[700],
),
child: Text(
'60',
style: TextStyle(fontSize: 20),
),
),
),
),
],
),
);
}
}
This one is an output of this page
enter image description here
You have a very interesting idea for a project. I can give out some clues on how you can implement it.
First, with the sensor package, you can listen to the orientation of the phone through the 3 BroadcastStream: accelerometerEvents, userAccelerometerEvents, and gyroscopeEvents. With this in mind, we can listen to the changes (particularly the x, y and z values) in the initState(), then manipulate the UI based on them.
To demonstrate better, I have here a full working example of just using accelerometer values to change the background of the app by first setting the orientation to Landscape (for simple demonstration), then listen to the z value. You can manipulate the text and other values as well to create the Heads Up! game of your own! Here are the codes:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sensors/sensors.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
]);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.indigo,
),
home: GameGuessWord(),
);
}
}
class GameGuessWord extends StatefulWidget {
#override
_GameGuessWordState createState() => _GameGuessWordState();
}
class _GameGuessWordState extends State<GameGuessWord> {
Color _backgroundColor = Colors.indigo;
/// Upright: [-10, 0, 0]
/// Tilt forward: [0, 0, -10]
/// Tilt backward: [0, 0, 10]
#override
void initState() {
super.initState();
accelerometerEvents.listen((AccelerometerEvent event) {
setState(() {
// Manipulate the UI here, something like:
if (event.z < -6) {
_backgroundColor = Colors.green;
} else if (event.z > 6) {
_backgroundColor = Colors.red;
} else {
_backgroundColor = Colors.indigo;
}
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: _backgroundColor,
body: Column(
// mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: (MediaQuery.of(context).size.height) / 2 - 60),
child: Text(
'FootBall',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 100,
color: Colors.white,
),
),
),
Container(
margin:
EdgeInsets.only(top: (MediaQuery.of(context).size.height / 8)),
padding: EdgeInsets.all(10),
child: Center(
child: Container(
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.amber[700],
),
child: Text(
'60',
style: TextStyle(fontSize: 20),
),
),
),
),
],
),
);
}
}

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()
]'''