I want when I click on the + Button it shows the next 3 containers that in the listVeiw it is horizontally direction.
Here is my code.
when I tap for the first time it works, but it doesn't work for the others taps
import 'package:flutter/material.dart';
class FindCars extends StatefulWidget {
const FindCars({Key? key}) : super(key: key);
#override
State<NewWayToFindCars> createState() => _NewWayToFindCarsState();
}
class _NewWayToFindCarsState extends State<NewWayToFindCars> {
var pricesListNumber = 10;
int counter = 1;
List months = [
'يناير',
'فبراير',
'مارس',
'ابريل',
'مايو',
'يونيو',
'يوليو',
'اغسطس',
'سبتمبر',
'اكتوبر',
'نوفمبر',
'ديسمبر'
];
var currentMonth = new DateTime.now().month;
var currentDay = new DateTime.now().day;
late ScrollController _scrollController;
#override
void initState() {
_scrollController = ScrollController();
super.initState();
}
#override
Widget build(BuildContext context) {
print(months[currentMonth - 1]);
print(currentDay);
print(DateTime.now());
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Directionality(
textDirection: TextDirection.rtl,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'${months[currentMonth - 1]} 2022',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
fontFamily: 'cairo',
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
_scrollController.animateTo(-200,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut);
},
child: Container(
child: Icon(Icons.remove, size: 22),
width: 50,
height: 50,
decoration: BoxDecoration(
color: Color(0xFFDCEDC8).withOpacity(0.5),
border: Border.all(
color: Color(0xFFDDE7DD).withOpacity(0.5),
width: 2.5,
),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
),
),
),
InkWell(
onTap: () {
_scrollController.animateTo(200,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut);
},
child: Container(
child: Center(child: Icon(Icons.add_sharp, size: 22)),
width: 50,
height: 50,
decoration: BoxDecoration(
color: Color(0xFFDCEDC8).withOpacity(0.25),
border: Border.all(
color: Color(0xFFDDE7DD).withOpacity(0.5),
width: 2.5,
),
borderRadius: BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
),
),
],
),
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.1,
child: ListView(
controller: _scrollController, // scroll contoller
scrollDirection: Axis.horizontal,
children: new List.generate(
pricesListNumber,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Center(child: Text('${currentDay++}')),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
color: Color(0xFFDCEDC8).withOpacity(0.5),
border: Border.all(
color: Color(0xFFDDE7DD).withOpacity(0.5),
width: 2.5,
),
borderRadius: BorderRadius.circular(10),
),
height: 50,
width: MediaQuery.of(context).size.width * 0.25,
),
),
),
),
),
],
),
),
);
}
}
Here is my code for the UI, and now it is only works in the first click put it does not work until the end.
Can you please help me with that?
Attach a ScrollController to your scrollable widget and then use scrollController.animateTo(//offset) to reach where you want.
Do check the animateTo method on this page.
EDIT:
sample code:
ScrollController scrollController = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter'),
centerTitle: true,
),
body: Column(
children: [
ElevatedButton(
onPressed: () {
scrollController.animateTo(0,
duration: Duration(seconds: 1), curve: Curves.easeIn);
},
child: Text("go top")),
Expanded(
flex: 1,
child: ListView.builder(
controller: scrollController,
itemCount: 100,
itemBuilder: (context, index) {
return Text('This is it.');
},
),
),
],
),
);
}
Try it in your IDE.
EDIT:
Here is the problem in your code, you need to decrease/increase the current offset of the scroll controller by subtracting/adding 200 from the scrollController.position. You are getting it moved for the first time because at that time offset is not at 200 and for the second time it is there at 200. That is why it is not moving which is obviously no error.
Just use a scrollController, attach it to your ListView builder,
then on your Button's onPress/onTap method, call _scrolController.animateTo(someOffset)
Copy the code below and run into your project. I have customized it based on your needs.
import 'package:flutter/material.dart';
class TestView extends StatefulWidget {
const TestView({Key? key}) : super(key: key);
#override
State<TestView> createState() => _TestViewState();
}
class _TestViewState extends State<TestView> {
late ScrollController _scrollController;
#override
void initState() {
_scrollController = ScrollController();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () {
_scrollController.animateTo(-500,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut);
},
child: const Text("-")),
ElevatedButton(
onPressed: () {
_scrollController.animateTo(500,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut);
},
child: const Text("+"),
),
],
),
SizedBox(
height: 200,
child: ListView(
controller: _scrollController,
scrollDirection: Axis.horizontal,
children: List.generate(20, (index) {
return Container(
color: Colors.amber,
height: 100,
width: 100,
margin: const EdgeInsets.only(right: 10),
child: Center(child: Text("$index")),
);
}),
),
)
],
),
);
}
}
Related
i am trying to update the state of the animated switcher in the middle area. i am trying to do this using a setstate in the lower area. but it does not work.
the first thing i did is to create a variable with a boolean data type in the home class.
then i passed the variable to both the middle area and the lower area
the idea was that if the same variable is passed to the class whose state i am trying to update, and the class with the set state, it would work. but it seems i am wrong. i would appreciate some assistance.
the boolean variable i am trying to make work is the _rep variable
This is the Home widget
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
late AnimationController _animationController;
late AnimationController _controller;
late Animation<Offset> _animation;
late Animation<Offset> _anime;
bool _rep = true;
#override
void initState() {
_animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 2)
);
_animation = Tween<Offset>(
begin:Offset (0.0, 0.0),
end: Offset (0.0,3.0),
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeIn));
_anime = Tween<Offset>(
begin:Offset (0.0, 0.0),
end: Offset (0.0,-0.55),
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeIn));
super.initState();
}
#override
void dispose() {
_animationController.dispose();
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
physics: const NeverScrollableScrollPhysics(),
child: Padding(
padding: EdgeInsets.only(top: 3.h),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TopIcon(icons: Icons.arrow_back, color:Colors.grey.shade300 ,),
SizedBox(
height: 13.h,
width: 13.w,
child: Image.asset('assets/images/download.png')
),
TopIcon(icons: Icons.shopping_bag_outlined, color: Colors.grey.shade300,),
],
),
SizedBox(
height: 3.h,
),
Text('Frappuccino',
style: TextStyle(
fontSize: 27.sp,
fontWeight: FontWeight.bold
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('White Chocolate',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey.shade400
),
),
),
MiddleArea(
controller: _animationController,
animation: _animation,
rep: _rep,
),
LowerArea(controller: _animationController, anime: _anime, rep = _rep),
],
),
),
),
);
}
}
This is the middle area
class MiddleArea extends StatefulWidget {
MiddleArea({Key? key, required this.controller, required this.animation, required this.rep}) : super(key: key);
AnimationController controller;
Animation<Offset> animation;
final bool rep;
#override
State<MiddleArea> createState() => _MiddleAreaState();
}
class _MiddleAreaState extends State<MiddleArea> {
bool _flag = true;
bool _favourite = true;
#override
Widget build(BuildContext context) {
print(widget.rep);
return SizedBox(
height: 52.h,
child: Stack(
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 135.0),
child: Text('STARBUCKS',
style: TextStyle(
fontFamily: 'Typette',
color: Colors.brown.shade200,
fontSize: 30.sp,
fontWeight: FontWeight.w400
),
),
),
Text('STARBUCKS',
style: TextStyle(
fontFamily: 'Typette',
color: Colors.brown.shade100,
fontSize: 30.sp,
fontWeight: FontWeight.w400
),
),
Text('STARBUCKS',
style: TextStyle(
fontFamily: 'Typette',
color: Colors.brown.shade50,
fontSize: 30.sp,
fontWeight: FontWeight.w400
),
),
],
),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
SizeAndFave(text: 'Preference'),
SizeAndFave(text: 'Fave!')
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: (){
setState(() {
_flag = !_flag;
});
},
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
transitionBuilder: (Widget child, Animation<double> animation){
return FadeTransition(opacity: animation, child: child,);
},
child: widget.rep == true?Padding(
padding: const EdgeInsets.all(14.0),
key: const Key('1'),
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
border: Border.all(
color: Colors.brown.shade300,
width: 3
),
borderRadius: BorderRadius.circular(10)
),
child: const Center(
child: Icon(
Icons.coffee_outlined,
size: 20,
),
)
),
):null,
)
),
GestureDetector(
onTap: (){
setState(() {
_favourite = !_favourite;
});
},
child: _favourite? TopIcon(icons: Icons.favorite_border, color: Colors.brown.shade300)
:TopIcon(
icons: Icons.favorite, color: Colors.brown.shade300)
)
],
)
],
),
AnimatedSwitcher(
duration: Duration(seconds: 1),
transitionBuilder: (Widget child, Animation<double> animation) {
return FadeTransition( opacity: animation,
child: child);
},
child: _flag == true ? Center(
key: const Key('1'),
child: SlideTransition(
position: widget.animation,
child: SizedBox(
height: 80.h,
width: 80.w,
child: Image.asset('assets/images/starcup.png'),
),
),
):Center(
key: const Key('2'),
child: SlideTransition(
position: widget.animation,
child: SizedBox(
height: 80.h,
width: 80.w,
child: Image.asset('assets/images/greeen.png'),
),
),
),
),
Positioned(
child:
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: EdgeInsets.only(top: 30.h),
child: TopIcon(
icons: Icons.car_crash_outlined, color: Colors.brown.shade300),
),
)),
const Positioned(
child:
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: EdgeInsets.only(top: 330.0, left: 14),
child: Text('\$ 5.99',
style: TextStyle(
fontSize: 27,
fontWeight: FontWeight.bold
),
),
),
))
],
),
);
}
}
and lastly, the lower area
class LowerArea extends StatefulWidget {
final AnimationController controller;
final Animation<Offset> anime;
bool rep;
LowerArea({Key? key, required this.controller, required this.anime, required this.rep}) : super(key: key);
#override
State<LowerArea> createState() => _LowerAreaState();
}
class _LowerAreaState extends State<LowerArea> {
bool _bigger = true;
bool _fade = true;
void move(){
}
#override
Widget build(BuildContext context) {
return Column(
children: [
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsets.all(1.h),
child: const Text('Tall Frappuccino',
style: TextStyle(
fontWeight: FontWeight.w500
),
),
),
Padding(
padding: EdgeInsets.only(right: 5.h),
child: const Text('Swipe Down',
style: TextStyle(
fontWeight: FontWeight.w500
),
),
),
Padding(
padding: EdgeInsets.all(2.h),
child: const Text('Pickup',
style: TextStyle(
fontWeight: FontWeight.w500
),
),
)
],
),
),
SlideTransition(
position: widget.anime,
child: AnimatedContainer(
// height: 11.h,
width: _bigger ? 35.h: 80.h,
duration: const Duration(milliseconds: 500),
child: Stack(
fit: StackFit.loose,
children: [
Center(child: Image.asset('assets/images/baggie.png')),
Center(
child: Padding(
padding: EdgeInsets.only(bottom: 4.h),
child: GestureDetector(
onTap: (){
widget.controller.forward();
setState(() {
_bigger = !_bigger;
_fade = !_fade;
widget.rep = !widget.rep;
print('this is fade $_fade ');
});
},
child: AnimatedSwitcher(
duration: Duration(milliseconds: 300),
transitionBuilder: (Widget child, Animation<double> animation){
return FadeTransition(opacity: animation, child: child,);
},
child: _fade? Container(
key: Key('1'),
height: 8.h,
width: 7.w,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(15)
),
child: Column(
children: [
Padding(
padding: EdgeInsets.all(0.3.h),
child: Icon(
Icons.lock_outline,
color: Colors.white54,
size: 2.5.h,
),
),
Icon(
Icons.arrow_drop_down,
color: Colors.white12,
size: 3.h,
),
],
),
):null,
),
),
),
)
],
),
),
)
],
);
}
use provider pacakges https://pub.dev/packages/provider
Create a class that inherits the functions of ChangeNotifyer to create a flag to control and create a setter.
provider class
class StateController extends ChangeNotifier{
bool _req = false;
bool get req => _req; //getter
setReqValue(){
_req = !_req;
notifyListener();
}
}
Declare the provider class in the main function. You can change the location of the declaration according to Wiget tree, but first declare it in main
Change main.dart
void main(){
runApp(
Multiprovider(
providers: [
ChangeNotifierProvider(create: (_) => StateController()),
],
child: HomePage(),
)
);
}
The UI is updated by notifyListener().
change UI
child: context.watch<StateController>().req == true ? Padding(
padding: const EdgeInsets.all(14.0),
key: const Key('1'),
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
border: Border.all(
color: Colors.brown.shade300,
width: 3
),
borderRadius: BorderRadius.circular(10)
),
child: const Center(
child: Icon(
Icons.coffee_outlined,
size: 20,
),
)
),
):null,
Change State
onTap: (){
widget.controller.forward();
setState(() {
_bigger = !_bigger;
_fade = !_fade;
context.read<StateController>().setReqValue();
print('this is fade $_fade ');
});
},
I am too lazy to try understand your code. But if you want to update state of the page after you pop from Navigation to it.
In page you want to update
Navigation.push(context, /* Page that will change something */)
// Future will trigger then you return to this page.
.then((_) => setState(() {}))
I Had Question For how create Scroll List Like this
Flutter Scroll List Over Header
According to the answers given, I used DraggableScrollableSheet for implementing this scroll view
but now i have new problem
The Result is here:
now I need to when im scrolling the top Child Stay On Top, like a header
how can do this?
Here is my Code
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
AppController appController = Provider.of<AppController>(context);
HomeController homeController = Provider.of<HomeController>(context);
String selectedCategory = homeController.selectedCategory;
return SafeArea(
child: Container(
//height: 450,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/home_header.png'),
alignment: Alignment.topCenter,
)),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
flexibleSpace: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: ChiscoAppbar(
icon: MENU,
iconAlignment: Alignment.centerLeft,
title: 'خانه',
onClick: () {
Navigator.pushNamed(context, '/account');
},
),
),
),
backgroundColor: Colors.transparent,
body: Stack(
children: [
Positioned(
child: Container(
color: Colors.transparent,
height: 200,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Expanded(
flex: 3,
child: Align(
alignment: Alignment.center,
child: ChiscoText(
text: 'دستگاههای هوشمند چیسکو',
fontWeight: FontWeight.w500,
textColor: Colors.white,
fontSize: 16,
)),
),
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
HeaderItem(
titleText: 'کنترلر',
icon: COOLER,
counterText: '2',
),
HeaderItem(
titleText: 'سه راهی',
icon: SOCKET,
counterText: '2',
)
],
),
)),
],
),
),
),
Positioned(
child: DraggableScrollableSheet(
expand: true,
minChildSize: 0.70,
maxChildSize: 0.95,
initialChildSize: 0.70,
builder: (context, scrollController) {
return SingleChildScrollView(
controller: scrollController,
child: Container(
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25))),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListHandlerView(),
Container(
margin: const EdgeInsets.fromLTRB(20, 8, 20, 10),
height: 30,
child: ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: appController
.listOfDevicesCategory.length,
scrollDirection: Axis.horizontal,
primary: true,
addSemanticIndexes: false,
itemBuilder: (context, index) {
String category = appController
.listOfDevicesCategory[index];
return CategoryListItem(
isSelected: selectedCategory == category,
category: category,
);
}),
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
],
),
),
);
},
),
)
],
),
floatingActionButton: Container(
margin: const EdgeInsets.only(bottom: 16),
child: const ChiscoSpeedDial()),
floatingActionButtonLocation:
FloatingActionButtonLocation.startDocked,
),
),
);
}
}
I think it is better to use bottom from SliverAppBar. Run below widget to see the result
class DAX extends StatefulWidget {
DAX({Key? key}) : super(key: key);
#override
State<DAX> createState() => _DAXState();
}
class _DAXState extends State<DAX> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: 200,
pinned: true,
backgroundColor: Colors.blue,
elevation: 0,
bottom: PreferredSize(
preferredSize: Size.fromHeight(60),
child: ColoredBox(
color: Colors.blue,
child: Container(
clipBehavior: Clip.hardEdge,
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
color: Colors.white,
),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
12,
(index) => Chip(
label: Text("chip $index"),
),
),
),
),
),
)),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
alignment: Alignment.center,
height: 100,
child: Text("$index"),
),
),
),
],
),
),
);
}
}
I'm new to Flutter and I just start coding the UI of a chat app so I figure out that my widget doesn't take all the space of the bottom navigation bar like the photo shows : shows
This is my camera widget code :
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
class Camera extends StatefulWidget {
#override
_CameraState createState() => _CameraState();
}
class _CameraState extends State<Camera> {
File _image;
final imagePicker = ImagePicker();
Future getImage() async {
final image = await imagePicker.getImage(source: ImageSource.camera);
setState(() {
_image = File(image.path);
});
}
#override
Widget build(BuildContext context) {
return SizedBox(
height: 100,
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 80.0,
height: 80.0,
child: FloatingActionButton(
backgroundColor: Colors.white,
onPressed: getImage,
child: Icon(
Icons.camera_alt_rounded,
color: Colors.lightBlue[600],
size: 35.0,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0))),
),
),
],
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.lightBlue[50],
boxShadow: [
BoxShadow(color: Colors.grey[100], spreadRadius: 3),
],
),
height: 50,
),
);
}
}
and this is the chat screen code :
import 'dart:io';
import 'package:mychat/services/auth.dart';
import 'package:flutter/material.dart';
import 'package:mychat/chat/chat.dart';
import 'package:mychat/widgets/Med_form.dart';
import 'package:mychat/widgets/bottomButtons.dart';
import 'package:mychat/widgets/camera.dart';
import 'package:mychat/widgets/incrementAndDecrement.dart';
import 'package:mychat/widgets/yesOrno.dart';
class ChatScreen extends StatefulWidget {
#override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
File _image;
final AuthService _auth = AuthService();
List<String> messages = [
'fizikefgzerpgr',
'fioezhfejzifojef',
'fvfzerfergnyolnkyokjy',
'rgop^l^lmf^prlgprgprp'
];
List<String> responses = [
'fizikefgzerpgr',
'fezfzefzefezff',
'ofpkoepzkfopkzef',
'fjeziofjiozejfozejf'
];
//final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(90),
child: AppBar(
title: new Text(
"لاباس ⸮",
style: TextStyle(
color: Colors.black,
fontSize: 30.0,
fontWeight: FontWeight.bold),
),
centerTitle: true,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomRight,
colors: [Colors.blueGrey[300], Colors.grey[50]])),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.arrow_forward_ios_outlined,
color: Colors.black,
),
onPressed: () async {
await _auth.signOut();
})
],
elevation: 0.0,
),
),
body: Chat_page(messages: messages, responses: responses),
bottomNavigationBar: Camera(),
),
));
}
}
and this is the code of the messages:
import 'package:bubble/bubble.dart';
import 'package:flutter/material.dart';
class Chat_page extends StatefulWidget {
List<String> messages;
List<String> responses;
Chat_page({this.messages, this.responses});
#override
_Chat_pageState createState() => _Chat_pageState();
}
class _Chat_pageState extends State<Chat_page> {
String message;
int data;
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
/* Container(
padding: EdgeInsets.only(top: 15, bottom: 10),
child: Text(
"Today, 10",
style: TextStyle(fontSize: 20, color: Colors.white),
),
), */
Flexible(
child: widget.messages.length > 0
? ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount: widget.messages.length,
itemBuilder: (context, index) => Column(
children: [
widget.messages.length > 0
? chat(widget.messages[index].toString(), 1)
: Container(),
widget.responses.length > 0
? chat(widget.responses[index].toString(), 0)
: Container(),
],
))
: Container(),
),
SizedBox(
height: 20,
),
SizedBox(
height: 15.0,
)
],
));
}
}
Widget chat(String message, int data) {
return Container(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
mainAxisAlignment:
data == 1 ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
data == 0
? Container(
height: 60,
width: 60,
child: CircleAvatar(
child: Icon(Icons.account_circle),
),
)
: Container(),
Padding(
padding: EdgeInsets.all(10.0),
child: Bubble(
radius: Radius.circular(15.0),
color: data == 0 ? Color(0xFFf7ede2) : Color(0xFFf7ede2),
elevation: 0.0,
child: Padding(
padding: EdgeInsets.all(2.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
width: 10.0,
),
Flexible(
child: Container(
constraints: BoxConstraints(maxWidth: 200),
child: Text(
message,
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),
),
))
],
),
)),
),
data == 1
? Container(
height: 60,
width: 60,
child: CircleAvatar(
child: Icon(Icons.account_circle),
),
)
: Container(),
],
),
);
}
so how can I fix this the make my camera widget take the full space
try to change
SizedBox(
height: 100,
child: Container(
to
Container(
height: 100,
width:double.infinty,
I am currently working on the ui stuff for the appliction, so the thing is i have one gesture as a parent that swipes up and down and based on it the position of the widgets gets changed but the problem is the child gesture does not get any precedence when tapped on it it gives the precedence. So my tree structure is Pageview.builder which has single widget with topmost parent as Gesturedetector and the children accrodingly, Can any one tell me what i am doing wrong or any improvements to get the gesture for each.
Below is the sample code that i have been working on:
import 'dart:math';
import 'package:LocationAnimation/Model/device_model.dart';
import 'package:LocationAnimation/SplashPage/splash_page.dart';
import 'package:LocationAnimation/widgets/device_function_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'Model/device_model.dart' as devices;
import 'Model/locations_model.dart' as locations;
import 'extensions/capitalize.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'HAL',
home: MyHomePage(),
);
}
}
class SampleList {
final String locationName;
SampleList({this.locationName});
}
class MyHomePage extends StatefulWidget {
#override
State createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
final _controller = new PageController();
final _kArrowColor = Colors.black.withOpacity(0.8);
bool _isSwipe = false;
bool _isLoading = false;
var list = [
SampleList(locationName: 'Living Room'),
SampleList(locationName: 'Bed Room'),
SampleList(locationName: 'Back Porch Lights'),
SampleList(locationName: 'Basement Porch Lights'),
SampleList(locationName: 'Sample Room'),
];
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new IconTheme(
data: new IconThemeData(color: _kArrowColor),
child: new Stack(
children: <Widget>[
new PageView.builder(
physics: _isSwipe
? NeverScrollableScrollPhysics()
: AlwaysScrollableScrollPhysics(),
controller: _controller,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return LocationDetails(
isLoading: _isLoading,
item: list[index],
onSwipeDown: () {
setState(() {
_isSwipe = false;
});
},
onSwipeUp: () {
setState(() {
_isSwipe = true;
});
},
);
},
),
],
),
),
);
}
}
class LocationDetails extends StatefulWidget {
final bool isLoading;
SampleList item;
final Function() onSwipeUp;
final Function() onSwipeDown;
LocationDetails(
{Key key, this.item, this.onSwipeUp, this.onSwipeDown, this.isLoading})
: super(key: key);
#override
_LocationDetailsState createState() => _LocationDetailsState();
}
class _LocationDetailsState extends State<LocationDetails> {
DragStartDetails startVerticalDragDetails;
DragUpdateDetails updateVerticalDragDetails;
bool moveWidget = false;
bool dismissSwipeText = true;
bool _isRotate = false;
int currentSelectedIndex = 0;
bool ignoreChildGestures = true;
bool _isSwpie = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
child: GestureDetector(
onTap: () {
print('Tap');
},
onVerticalDragStart: (dragDetails) {
startVerticalDragDetails = dragDetails;
},
onVerticalDragUpdate: (dragDetails) {
updateVerticalDragDetails = dragDetails;
},
onVerticalDragEnd: (endDetails) {
double dx = updateVerticalDragDetails.globalPosition.dx -
startVerticalDragDetails.globalPosition.dx;
double dy = updateVerticalDragDetails.globalPosition.dy -
startVerticalDragDetails.globalPosition.dy;
double velocity = endDetails.primaryVelocity;
//Convert values to be positive
if (dx < 0) dx = -dx;
if (dy < 0) dy = -dy;
if (velocity < 0) {
widget.onSwipeUp();
print('drag up');
setState(() {
moveWidget = true;
_isSwpie = true;
});
} else {
widget.onSwipeDown();
print(' drag down');
setState(() {
moveWidget = false;
_isSwpie = false;
});
}
},
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: new BoxDecoration(
image: new DecorationImage(
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.8), BlendMode.srcOver),
image: /* moveWidget
? */
AssetImage(
'Assets/backgroundImage.jpg',
),
/* : NetworkImage(widget.samplePage.networkImage), */
fit: BoxFit.fill,
),
),
child:
/* widget.isLoading
? Center(
child: CircularProgressIndicator(),
)
: */
Stack(
children: <Widget>[
AnimatedOpacity(
opacity: moveWidget ? 0 : 1,
duration: Duration(microseconds: 100),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: <Widget>[
Icon(
Icons.power_settings_new,
color: Colors.white,
size: 30,
),
Icon(
Icons.more_horiz,
color: Colors.white,
size: 25,
)
],
),
Row(
children: <Widget>[
Column(
children: <Widget>[
Text(
'Inside Temp',
style: TextStyle(
color: Colors.white, fontSize: 18),
),
SizedBox(
height: 5,
),
Row(
children: <Widget>[
Icon(
Icons.ac_unit,
color: Colors.white,
size: 20,
),
SizedBox(
width: 10,
),
Text(
'19 C',
style: TextStyle(color: Colors.white),
),
],
)
],
),
SizedBox(
width: 10,
),
Column(
children: <Widget>[
Text(
'Outside Temp',
style: TextStyle(
color: Colors.white, fontSize: 18),
),
SizedBox(
height: 5,
),
Row(
children: <Widget>[
Icon(
Icons.ac_unit,
color: Colors.white,
size: 20,
),
SizedBox(
width: 10,
),
Text(
'19 C',
style: TextStyle(color: Colors.white),
),
],
)
],
),
],
)
],
),
),
),
AnimatedPositioned(
onEnd: () {
setState(() {
dismissSwipeText = !dismissSwipeText;
//print(dismissSwipeText);
});
},
curve: Curves.ease,
duration: Duration(milliseconds: 700),
bottom: moveWidget
? 10
: MediaQuery.of(context).size.height * 0.18,
left: 10.0,
right: 0.0,
top: moveWidget
? 50
: MediaQuery.of(context).size.height * 0.75,
child: AnimatedOpacity(
opacity: dismissSwipeText ? 1 : 0,
duration: Duration(milliseconds: 500),
child: Text(
'Swipe up to customize',
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
AnimatedPositioned(
curve: Curves.ease,
duration: Duration(milliseconds: 700),
onEnd: () {
setState(() {
_isSwpie = true;
});
},
left: 10,
top: moveWidget
? 80
: MediaQuery.of(context).size.height * 0.80,
child: Container(
width: MediaQuery.of(context).size.width * 0.97,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
currentSelectedIndex = 0;
});
},
child: Container(
width: MediaQuery.of(context).size.width * 0.20,
height:
MediaQuery.of(context).size.height * 0.10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: currentSelectedIndex == 0
? Colors.blue
: Colors.grey[900],
),
child: Center(
child: Text(
'Lights',
style: GoogleFonts.lato(
color: Colors.white,
fontWeight: FontWeight.w700),
)),
),
),
Row(
children: <Widget>[
SizedBox(
width: 10,
),
GestureDetector(
onTap: () {
setState(() {
currentSelectedIndex = 1;
});
},
child: Container(
width: MediaQuery.of(context).size.width *
0.20,
height: MediaQuery.of(context).size.height *
0.10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: currentSelectedIndex == 1
? Colors.blue
: Colors.grey[900],
),
child: Center(
child: Text(
'Applicanes',
style: GoogleFonts.lato(
color: Colors.white,
fontWeight: FontWeight.w700),
)),
),
),
],
),
Row(
children: <Widget>[
SizedBox(
width: 10,
),
GestureDetector(
onTap: () {
setState(() {
currentSelectedIndex = 2;
});
},
child: Container(
width: MediaQuery.of(context).size.width *
0.20,
height: MediaQuery.of(context).size.height *
0.10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: currentSelectedIndex == 2
? Colors.blue
: Colors.grey[900],
),
child: Center(
child: Text(
'Sensors',
style: GoogleFonts.lato(
color: Colors.white,
fontWeight: FontWeight.w700),
)),
),
),
],
),
Row(
children: <Widget>[
SizedBox(
width: 10,
),
Container(
width:
MediaQuery.of(context).size.width * 0.20,
height:
MediaQuery.of(context).size.height * 0.10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.grey[900],
),
child: Center(
child: Text(
'Doors \n& Locks',
style: GoogleFonts.lato(
color: Colors.white,
fontWeight: FontWeight.w700),
)),
),
],
),
SizedBox(
width: 10,
),
],
),
),
),
AnimatedPositioned(
curve: Curves.ease,
duration: Duration(milliseconds: 400),
bottom: moveWidget
? 10
: MediaQuery.of(context).size.height * 0.20,
left: 10.0,
right: 0.0,
top: moveWidget
? 15
: MediaQuery.of(context).size.height * 0.70,
child: Text(
'${widget.item.locationName}',
style: TextStyle(fontSize: 30, color: Colors.white),
),
),
],
)),
),
),
),
);
}
}
You can add Color to the last AnimatedPositioned which use text widget.item.locationName in your code, like:
AnimatedPositioned(
curve: Curves.ease,
duration: Duration(milliseconds: 400),
bottom: moveWidget
? 10
: MediaQuery.of(context).size.height * 0.20,
left: 10.0,
right: 0.0,
top: moveWidget
? 15
: MediaQuery.of(context).size.height * 0.70,
child: Container(
color: Colors.white,
Text(
'${widget.item.locationName}',
style: TextStyle(fontSize: 30, color: Colors.white),
),
),
),
You will see a white screen (the widget which blocking you) when you scroll up. You can fix it by 2 ways
Change the bottom 10 to a larger number
Move this part of AnimatedPositioned to Top of the Stack widget
The Nested Gesture should work probably as you expected.
First of All you are using multiple Scaffold in a single page which is not recommended.
And remove the unwanted widgets from your tree which will help you to debug a way more better level. And Next you can try with passing a Callback function from parent to child which can eventually solve your problem
I am building a food cart application and have a query on the menu item page.
My menu items page consists of a list view, which shows each item with description along with an option to specify the quantity of items( 1, 2, 3....)
Now I am able to increment or decrement item count for a single item, but not sure how to do that in a list view at a particular index where the user clicks.
Could some one please help me on this?
The code which I have done till now is as below :
FutureBuilder(
future: getItemList(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
var itemList = snapshot.data;
int itemlength = itemList.length;
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
margin: EdgeInsets.only(left: 10, right: 10, top: 10),
decoration: BoxDecoration(
color: Colors.white70,
border: Border.all(width: 2.0, color: Colors.blueGrey),
borderRadius: BorderRadius.circular(6.0),
boxShadow: [
BoxShadow(
color: Color(0xFF6078ea).withOpacity(.3),
offset: Offset(0.0, 8.0),
blurRadius: 8.0),
],
),
child: Row(
children: < Widget > [
Container(
width: 75,
child: ClipRRect(
borderRadius: new BorderRadius.circular(10.0),
child: Image(
image: AssetImage(
'assets/images/loginbg3.jpg'),
fit: BoxFit.cover,
),
),
margin: EdgeInsets.only(left: 10),
),
Expanded(
child: Container(
child: Column(
children: < Widget > [
Row(
children: < Widget > [
Expanded(child: Container(margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Text(itemList[index]['itemname'], style: kClickableTextStyle, ))),
Container(color: Colors.white, width: 25, margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Image.asset(_itemtype)),
],
),
Row(
children: < Widget > [
Container(margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Text('Price : ', style: kListTitleTextStyle, )),
Container(margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Text(numberofitems.toString() + ' \u20B9 ', style: kListTitleTextStyle, )),
],
),
],
),
),
),
Container(
margin: EdgeInsets.only(left: 10),
child: Row(
children: < Widget > [
InkWell(
onTap: onClickDelete,
child: Container(
width: 30, child: Icon(
Icons.remove_circle_outline,
color: Colors.green,
size: 30,
), ),
),
Container(
width: 30,
child: Center(child: Text(_count.toString(), style: TextStyle(fontSize: 25), )),
),
InkWell(
onTap: onClickAdd,
child: Container(
margin: EdgeInsets.only(right: 5),
width: 30, child: Icon(
Icons.add_circle_outline,
color: Colors.green,
size: 30,
), ),
),
],
),
),
],
),
);
},
itemCount: itemList == null ? 0 : itemList.length,
);
})
You can copy paste run full code below
Step 1: create Item class
Step 2: change future builder call
Step 3: deal with Inkwell onTap
working demo
code snippet
Future callback;
#override
void initState() {
callback = _getItemList();
super.initState();
}
#override
Widget build(BuildContext context) {
var futureBuilder = FutureBuilder(
future: callback,
...
InkWell(
onTap: () {
if (itemList[index].numberofitems > 0) {
setState(() {
itemList[index].numberofitems =
itemList[index].numberofitems - 1;
});
}
},
...
InkWell(
onTap: () {
setState(() {
itemList[index].numberofitems =
itemList[index].numberofitems + 1;
print(
' ${itemList[index].itemname.toString()} ${itemList[index].numberofitems.toString()}');
});
},
full code
import 'dart:async';
import 'dart:collection';
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 Item {
String itemname;
String itemtype;
int numberofitems;
Item({this.itemname, this.itemtype, this.numberofitems});
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future callback;
#override
void initState() {
callback = _getItemList();
super.initState();
}
#override
Widget build(BuildContext context) {
var futureBuilder = FutureBuilder(
future: callback,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else
return createListView(context, snapshot);
}
},
);
return Scaffold(
appBar: AppBar(
title: Text("Home Page"),
),
body: futureBuilder,
);
}
Future<List<Item>> _getItemList() async {
var values = List<Item>();
values.add(
Item(itemname: "A", itemtype: "assets/images/a.jpg", numberofitems: 0));
values.add(
Item(itemname: "B", itemtype: "assets/images/a.jpg", numberofitems: 1));
values.add(
Item(itemname: "C", itemtype: "assets/images/a.jpg", numberofitems: 2));
//throw Exception("Danger Will Robinson!!!");
await Future.delayed( Duration(seconds: 2));
return values;
}
Widget createListView(BuildContext context, AsyncSnapshot snapshot) {
List<Item> itemList = snapshot.data;
return ListView.builder(
itemCount: itemList.length,
itemBuilder: (BuildContext context, int index) {
{
return Container(
height: 100,
margin: EdgeInsets.only(left: 10, right: 10, top: 10),
decoration: BoxDecoration(
color: Colors.white70,
border: Border.all(width: 2.0, color: Colors.blueGrey),
borderRadius: BorderRadius.circular(6.0),
boxShadow: [
BoxShadow(
color: Color(0xFF6078ea).withOpacity(.3),
offset: Offset(0.0, 8.0),
blurRadius: 8.0),
],
),
child: Row(
children: <Widget>[
Container(
width: 75,
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image(
image: AssetImage('assets/images/a.jpg'),
fit: BoxFit.cover,
),
),
margin: EdgeInsets.only(left: 10),
),
Expanded(
child: Container(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
margin: EdgeInsets.only(
left: 10, top: 15, bottom: 5),
child: Text(
itemList[index].itemname,
))),
Container(
color: Colors.white,
width: 25,
margin: EdgeInsets.only(
left: 10, top: 15, bottom: 5),
child: Image.asset(itemList[index].itemtype)),
],
),
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(
left: 10, top: 15, bottom: 5),
child: Text(
'Price : ',
)),
Container(
margin: EdgeInsets.only(
left: 10, top: 15, bottom: 5),
child: Text(
itemList[index].numberofitems.toString() +
' \u20B9 ',
)),
],
),
],
),
),
),
Container(
margin: EdgeInsets.only(left: 10),
child: Row(
children: <Widget>[
InkWell(
onTap: () {
if (itemList[index].numberofitems > 0) {
setState(() {
itemList[index].numberofitems =
itemList[index].numberofitems - 1;
});
}
},
child: Container(
width: 30,
child: Icon(
Icons.remove_circle_outline,
color: Colors.green,
size: 30,
),
),
),
Container(
width: 30,
child: Center(
child: Text(
itemList[index].numberofitems.toString(),
style: TextStyle(fontSize: 25),
)),
),
InkWell(
onTap: () {
setState(() {
itemList[index].numberofitems =
itemList[index].numberofitems + 1;
print(
' ${itemList[index].itemname.toString()} ${itemList[index].numberofitems.toString()}');
});
},
child: Container(
margin: EdgeInsets.only(right: 5),
width: 30,
child: Icon(
Icons.add_circle_outline,
color: Colors.green,
size: 30,
),
),
),
],
),
),
],
),
);
}
;
});
}
}
you need to create list of objects for your Item like.
class Item{
String name;
String description;
int quantity;
double price;
}
and on tap of item, get index of clicked item with new incremented/decremented value and update your list of objects inside setState().
You need to wrap your itemBuilder item, i.e the Container with a GestureDetector and then call the onTap() method inside that detector.
Before that, you'll have to convert your item into a stateful widget with a variable to maintain the count of quantity.