Missing Identifier in Dart - android

I am new to coding and I am trying to write a simple app that would basicaly flip the top card of a deck and place it face up next to it.
I keep getting errors like "missing_identifier".
Below is my code, and I would really appreciate if I can get help getting it to work. "easy to understand" replies for a newbie would be appreciated.
Cheers.
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class Card {
final String cardName;
final int cardValue;
bool revealed;
Card({required this.cardName, required this.cardValue, this.revealed = false});
}
final List<Card> deck = [
Card(cardName: "Joker", cardValue: 0),
Card(cardName: "Joker", cardValue: 0),
Card(cardName: "King of Hearts", cardValue: 13),
Card(cardName: "King of Hearts", cardValue: 13),
// Add more cards here
child: CardPile(
key: UniqueKey(),
card: card,
),
];
final List<Card> discardPile = [];
class CardPile extends StatelessWidget {
final Card card;
CardPile({required this.card, Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
if (card.revealed)
Image.asset("assets/images/card_${card.cardName}.png"),
else
Image.asset("assets/images/card_back.png"),
],
);
}
}
class _GameScreenState extends State<GameScreen> {
final List<Card> deck = [
Card(cardName: "Joker", cardValue: 0),
Card(cardName: "Joker", cardValue: 0),
Card(cardName: "King of Hearts", cardValue: 13),
Card(cardName: "King of Hearts", cardValue: 13),
// Add more cards here
];
final List<Card> discardPile = [];
#override
void initState() {
super.initState();
_shuffleDeck();
}
void _shuffleDeck() {
deck.shuffle();
}
void _onRestart() {
setState(() {
_shuffleDeck();
discardPile.clear();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.black,
child: Column(
children: <Widget>[
Spacer(),
Expanded(
child: Stack(
children: <Widget>[
Positioned(
left: 0,
top: 0,
bottom: 0,
child: Container(
width: MediaQuery.of(context).size.width / 2,
child: ListView(
children: deck.map((card) => GestureDetector(
onTap: () {
setState(() {
deck.remove(card);
discardPile.add(card);
card.revealed = true;
});
},
child: CardPile(
card: card,
)))
.toList(),
),
),
),
Positioned(
right: 0,
top: 0,
bottom: 0,
child: Container(
width: MediaQuery.of(context).size.width / 2,
child: ListView(
children: discardPile
.map((card) => CardPile(
card: card,
))
.toList(),
),
),
),
if (deck.isEmpty)
Center(
child: RaisedButton(
onPressed: _onRestart,
child: Text("Restart"),
),
)
],
),
),
Spacer(),
Container(
width: double.infinity,
height: 50,
child: RaisedButton(
onPressed: _shuffleDeck,
child: Text(
"Play",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
],
),
),
);
}
}
class GameScreen extends StatefulWidget {
#override
_GameScreenState createState() => _GameScreenState();
}
void main() {runApp(MaterialApp(
home: GameScreen(),
));
}
I tried to remove the "else" statement, define "key" and "RaisedButton". I am lost

Related

GridView in Flutter

I'm working on a flutter project and I made a GridView with images and titles but I want the title to be outside the square, If I make padding they give this error BOTTOM OVERFLOWED BY 32 PIXELS. Any help is highly appreciated.
this is my code :
Card makeDashboardItem(String title, String img, int index) {
return Card(
elevation: 2,
margin: const EdgeInsets.all(3),
child: Container(
child: InkWell(
onTap: () {
setState(() {
isLoading = true;
});
_splitScreen2(index);
},
child: Column(
children: <Widget>[
const SizedBox(height: 10),
Center(
child: Image.asset(img,
alignment: Alignment.center),
),
const SizedBox(height: 1),
Center(
child: Text(
title,
style: const TextStyle(
fontSize: 13,
color: Colors.black,
),
),
),
],
),
),
),
);
}
Check DartPad
The Main problem was overflow so we wrap Expanded widget on Image widget.
Nb: Remove Expanded widget from Image widget You can see the difference
CardWidget
class ItemWidget extends StatelessWidget {
var data;
ItemWidget(this.data, {Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 150,
child: Card(
child: Column(
children: [
Expanded(
child: Container(
height: 125,
child: Image.network(
data["Image"],
alignment: Alignment.center,
fit: BoxFit.cover,
),
),
),
Center(
child: Text(
data["Name"],
style: TextStyle(fontSize: 12),
))
],
),
),
);
}
}
Fullcode
import 'package:flutter/material.dart';
runApp(
MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()),
);
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
var list = [
{
"Name": "ElectroniQues",
"Image":
"https://ecommerce.ccc2020.fr/wp-content/uploads/2020/10/electronic-gadgets.jpeg"
},
{
"Name": "Accessories",
"Image":
"https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/classic-accessories-1516305397.jpg"
},
{
"Name": "Hommes",
"Image":
"https://teja12.kuikr.com/is/a/c/880x425/gallery_images/original/cf5d08bff955e71.gif"
},
{
"Name": "Femmes",
"Image":
"https://cdn.pixabay.com/photo/2013/07/13/14/08/apparel-162192_1280.png"
},
{
"Name": "Enfants",
"Image": "https://images.indianexpress.com/2019/09/toys.jpg"
},
{
"Name": "Sunglasses",
"Image": "https://m.media-amazon.com/images/I/51zEsraniRL._UX569_.jpg"
},
{
"Name": "ElectroniQues",
"Image":
"https://ecommerce.ccc2020.fr/wp-content/uploads/2020/10/electronic-gadgets.jpeg"
},
{
"Name": "Accessories",
"Image":
"https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/classic-accessories-1516305397.jpg"
},
{
"Name": "Hommes",
"Image":
"https://teja12.kuikr.com/is/a/c/880x425/gallery_images/original/cf5d08bff955e71.gif"
},
{
"Name": "Femmes",
"Image":
"https://cdn.pixabay.com/photo/2013/07/13/14/08/apparel-162192_1280.png"
},
{
"Name": "Enfants",
"Image": "https://images.indianexpress.com/2019/09/toys.jpg"
},
{
"Name": "Sunglasses",
"Image": "https://m.media-amazon.com/images/I/51zEsraniRL._UX569_.jpg"
},
];
var column = Column(mainAxisAlignment: MainAxisAlignment.start, children: [
...list.map((e) {
return GestureDetector(onTap:(){},child: ItemWidget(e));
}).toList()
]);
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Row(
children: [
SideWidget(),
Expanded(
child: Scaffold(
bottomNavigationBar: buildBottomNavigationBar(),
body: Padding(
padding: const EdgeInsets.only(top: 18.0),
child:
// column
GridView.count(
crossAxisCount: 3,
mainAxisSpacing: 2,
crossAxisSpacing: 2,
children: [
...list.map((e) {
return InkWell(onTap:(){},child: ItemWidget(e));
}).toList()
],
),
),
),
),
],
),
),
);
}
BottomNavigationBar buildBottomNavigationBar() {
return BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: 0,
selectedItemColor: Colors.amber[800],
onTap: (v) {},
);
}
}
class SideWidget extends StatelessWidget {
const SideWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Material(
child: Container(
width: 63,
color: Colors.white,
child: ListView(
children: [
...[
Icons.headset,
Icons.pets,
Icons.watch,
Icons.color_lens,
Icons.today
]
.map((e) => Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0, horizontal: 4.0),
child: TextButton(
onPressed: () {},
child: Icon(
e,
color: Colors.blueGrey,
size: 40,
),
),
))
.toList()
],
),
),
);
}
}
class ItemWidget extends StatelessWidget {
var data;
ItemWidget(this.data, {Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 150,
child: Card(
child: Column(
children: [
Expanded(
child: Container(
height: 125,
child: GridTile(
// footer:Text(data["Name"]) ,
child: Image.network(
data["Image"],
alignment: Alignment.center,
fit: BoxFit.cover,
),
),
),
),
Center(
child: Text(
data["Name"],
style: TextStyle(fontSize: 12),
))
],
),
),
);
}
}
GridView children size depends on aspect ratio, which is 1 by default. In your case, image is not getting proper height.
For your case, You can use fit on Image.asset.
Image.asset(
"",
fit: BoxFit.cover, // or the .width or the one you prefer
),
Also you can try GridTile
GridTile(
child: Image.asset(
"",
fit: BoxFit.cover,
),
footer: Text("title"),
),
More about GridTile and BoxFit.
Firstly, the way you have created the widget tree is not proper.
Currently, you have
Card -> Container -> Column -> 1. Image
2. Text
If you want the title to be out of your square (Card), it should be:
Column -> 1. Card -> Image
2. Text
This way your title will be out of the card.

Flutter- Can border radius be given to Expansion Panel list? If yes, what are the properties that should be used

I have this code for expansion panel list which is working fine but I am not able to extend the size of the expansion panel. Also, I want the expansion panel to have a border radius but I am not sure if border radius can be given
return Column(children: [
Stack(
clipBehavior: Clip.none,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return Column(
children: [
Text("Salmon Poké"),
Text("Rs. 2000"),
],
);
},
body: Text(
'This salmon sashimi is a delicious light appetizer served with fresh wasabi, ginger, soy sauce or a delicious side of soy yuzo citrus ponzu.',
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
isExpanded: _expanded,
canTapOnHeader: true,
backgroundColor: Colors.white),
],
dividerColor: Colors.grey,
expansionCallback: (panelIndex, isExpanded) {
_expanded = !_expanded;
setState(() {});
},
),
),
Positioned(
top: -55,
right: 240,
child: CircleAvatar(
radius: 105,
child: ClipOval(
child: Image(
image: AssetImage('assets/images/salmon.png'),
),
),
backgroundColor: Colors.transparent,
),
),
],
),
]);
}
}
**Here is the UI for the given code **
This is the output I have.
Here is the output which I want. (This UI is made using container widgets but I want this layout using expansion panel list)
This is the output that I want
I really appreciate your help.
For border radius we need to make custom expansion list
import 'package:flutter/material.dart';
const double _kPanelHeaderCollapsedHeight = 48.0;
const double _kPanelHeaderExpandedHeight = 64.0;
class CustomExpansionPanelList extends StatelessWidget {
const CustomExpansionPanelList(
{Key key,
this.children: const <ExpansionPanel>[],
this.expansionCallback,
this.animationDuration: kThemeAnimationDuration})
: assert(children != null),
assert(animationDuration != null),
super(key: key);
final List<ExpansionPanel> children;
final ExpansionPanelCallback expansionCallback;
final Duration animationDuration;
bool _isChildExpanded(int index) {
return children[index].isExpanded;
}
#override
Widget build(BuildContext context) {
final List<Widget> items = <Widget>[];
const EdgeInsets kExpandedEdgeInsets = const EdgeInsets.symmetric(
vertical: _kPanelHeaderExpandedHeight - _kPanelHeaderCollapsedHeight);
for (int index = 0; index < children.length; index += 1) {
if (_isChildExpanded(index) && index != 0 && !_isChildExpanded(index - 1))
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 - 1),
height: 15.0,
color: Colors.transparent,
));
final Row header = new Row(
children: <Widget>[
new Expanded(
child: new AnimatedContainer(
duration: animationDuration,
curve: Curves.fastOutSlowIn,
margin: _isChildExpanded(index)
? kExpandedEdgeInsets
: EdgeInsets.zero,
child: new SizedBox(
height: _kPanelHeaderCollapsedHeight,
child: children[index].headerBuilder(
context,
children[index].isExpanded,
),
),
),
),
new Container(
margin: const EdgeInsetsDirectional.only(end: 8.0),
child: new ExpandIcon(
isExpanded: _isChildExpanded(index),
padding: const EdgeInsets.all(16.0),
onPressed: (bool isExpanded) {
if (expansionCallback != null)
expansionCallback(index, isExpanded);
},
),
),
],
);
double _radiusValue = _isChildExpanded(index)? 8.0 : 0.0;
items.add(
new Container(
key: new _SaltedKey<BuildContext, int>(context, index * 2),
child: new Material(
elevation: 2.0,
borderRadius: new BorderRadius.all(new Radius.circular(_radiusValue)),
child: new Column(
children: <Widget>[
header,
new AnimatedCrossFade(
firstChild: new Container(height: 0.0),
secondChild: children[index].body,
firstCurve:
const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve:
const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: _isChildExpanded(index)
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: animationDuration,
),
],
),
),
),
);
if (_isChildExpanded(index) && index != children.length - 1)
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 + 1),
height: 15.0,
));
}
return new Column(
children: items,
);
}
}
class _SaltedKey<S, V> extends LocalKey {
const _SaltedKey(this.salt, this.value);
final S salt;
final V value;
#override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final _SaltedKey<S, V> typedOther = other;
return salt == typedOther.salt && value == typedOther.value;
}
#override
int get hashCode => hashValues(runtimeType, salt, value);
#override
String toString() {
final String saltString = S == String ? '<\'$salt\'>' : '<$salt>';
final String valueString = V == String ? '<\'$value\'>' : '<$value>';
return '[$saltString $valueString]';
}
}
Now use this widget in your application
import 'package:color_essence/customViews/CustomExpansionList.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class ExpansionPanelDemo extends StatefulWidget {
#override
_ExpansionPanelDemoState createState() => _ExpansionPanelDemoState();
}
class _ExpansionPanelDemoState extends State<ExpansionPanelDemo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Expansion Panel Demo'),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView.builder(
itemCount: itemData.length,
itemBuilder: (BuildContext context, int index) {
return CustomExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
body: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipOval(
child: CircleAvatar(
child: Image.asset(
itemData[index].img,
fit: BoxFit.cover,
),
),
),
SizedBox(
height: 30,
),
Text(
itemData[index].discription,
style: TextStyle(
color: Colors.grey[700],
fontSize: 15,
letterSpacing: 0.3,
height: 1.3),
),
],
),
),
headerBuilder: (BuildContext context, bool isExpanded) {
return Container(
padding: EdgeInsets.all(10),
child: Text(
itemData[index].headerItem,
style: TextStyle(
color: itemData[index].colorsItem,
fontSize: 18,
),
),
);
},
isExpanded: itemData[index].expanded,
)
],
expansionCallback: (int item, bool status) {
setState(() {
itemData[index].expanded = !itemData[index].expanded;
});
},
);
},
),
),
);
}
List<ItemModel> itemData = <ItemModel>[
ItemModel(
headerItem: 'Android',
discription:
"Android is a mobile operating system based on a modified version of the Linux kernel and other open source software, designed primarily for touchscreen mobile devices such as smartphones and tablets. ... Some well known derivatives include Android TV for televisions and Wear OS for wearables, both developed by Google.",
colorsItem: Colors.green,
img: 'assets/images/android_img.png'
),
];
}
class ItemModel {
bool expanded;
String headerItem;
String discription;
Color colorsItem;
String img;
ItemModel({this.expanded: false, this.headerItem, this.discription,this.colorsItem,this.img});
}
Wrap the ExpansionPanelList in a ClipRRect.
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: ExpansionPanelList(
children: [ExpansionPanel(body: Text('Hello World'))])
)

Flutter _scaffoldKey.currentState.openDrawer() doesn't work

I have the following problem: I have the main class which shows me an image, which calls the drawer. So far it works fine, but when I call another class in the body (CardApplications), the drawer doesn't work. I still don't know how to fix it.
When i don't call class
"CrearAplicaciones" the drawer is called correctly with _scaffoldKey, but if I call it absolutely nothing happens, not even an error.
class HomeUsuario extends StatefulWidget {
final StorageClass storage;
HomeUsuario({Key key, #required this.storage}) : super(key: key);
#override
HomeUsuarioState createState() => HomeUsuarioState();
}
class HomeUsuarioState extends State<HomeUsuario> {
final prefs = PreferenciasUsuario();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Application app;
#override
// guardo en el documento global la información del usuario.
void initState() {
widget.storage.writeData(
'["${prefs.codigo}","${prefs.ciudad}","${prefs.oficina}","${prefs.seccion}"]');
widget.storage.readData();
super.initState();
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
key: _scaffoldKey,
drawer: MenuWidget(),
body: Stack(
children: [
Padding(
padding: EdgeInsets.only(left: size.width*0.7,top: size.height*0.1),
child: InkWell(
onTap: () => _scaffoldKey.currentState.openDrawer(),
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset('assets/images/USUARIO_ICONO.png',
width: 110.0,
height: 110.0
),
),
),
),
),
Container(
color: Colors.white70,
padding: EdgeInsets.only(
left: size.height * 0.02,
right: size.height * 0.02,
top: size.height * 0.1),
child: SingleChildScrollView(
child: Column(children: <Widget>[
ListTile(
leading: Icon(
FontAwesomeIcons.thLarge,
color: Colors.red,
),
title: Text(
'Mis aplicaciones',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.red),
),
),
]))),
CardAPlicaciones(),
],
),
);
}
}
class CardAPlicaciones extends StatelessWidget {
#override
Widget build(BuildContext context) {
final servicesProvider = ServiciosLogin();
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/FONDO.png"),
fit: BoxFit.cover,
)),
child: Padding(
padding: const EdgeInsets.fromLTRB(40, 100, 0, 0),
child: FutureBuilder(
future: servicesProvider.listarApps(),
builder: (BuildContext context,
AsyncSnapshot<List<Aplicacion>> snapshot) {
if (snapshot.hasData) {
final aplicaciones = snapshot.data;
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: aplicaciones.length,
itemBuilder: (BuildContext context, int index) {
return new _Card(aplicaciones[index]);
});
} else {
return Center(child: CircularProgressIndicator());
}
}),
),
);
}
// obtiene la informacion de la app instalada
}
class _Card extends StatelessWidget {
final Aplicacion app;
_Card(this.app);
#override
Widget build(BuildContext context) {
return Container(
child: Stack(
children: <Widget>[
Row(
children: <Widget>[
SizedBox(width: 10.0),
],
),
Positioned(
top: 35,
left: 0,
child: Column(
children: <Widget>[
new RawMaterialButton(
onPressed: () => {DeviceApps.openApp(app.paquete)},
child: CircleAvatar(
backgroundColor: Colors.white,
radius: 50,
backgroundImage: NetworkImage(global.url + app.icono),
)),
Text(app.nombre,
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold)),
],
))
],
),
);
}
}
Try this, put the InkWell inside a Builder to get the context of the scaffold.
child: Builder(scaffoldContext){
return InkWell(
onTap: () => Scaffold.of(scaffoldContext).currentState.openDrawer(),
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset('assets/images/USUARIO_ICONO.png',
width: 110.0,
height: 110.0
),
),
),
),
}

Is it possible to implement widgets using list in flutter?

I am creating a Journal mobile application which would work as a medium to view magazines and daily news updates. This is my first flutter project and I am totally new to flutter. So kindly excuse me if I had said something wrong about something or didnt provide enough information.
I used a code from github for the main page of my application and made few changes to accommodate my needs. Now in my code, the home page consists of a side menu bar and this bar consists of 4 buttons, namely Home, My Profile, Premium and FAQ. The GlobalKeys for the side menu bar is called using a list by the name _keys which is of the type GlobalKey. I tried changing the data type of the list _keys to Widget and then called the corresponding Widgets of the classes. But then two errors popped out.
The getter 'currentContext' isn't defined for the class 'Widget'.
The argument type 'Widget' can't be assigned to the parameter type 'GlobalKey<State>'.
Now I would like the list _keys to be of the type Widget in order for me to call upon it's corresponding widgets of Home, My Profile, Premium and FAQ from each of it's classes in order for me to view the corresponding pages. Or if it is not possible, I would love to know an alternative for it to start working.
Following is the code of my application.
import 'dart:math' as math;
import 'package:flutter/scheduler.dart';
import 'package:google_signin_example/google%20sign%20in/logged_in_widget.dart';
import 'package:google_signin_example/main app/lib/ui_3/TravelBean.dart';
import 'package:google_signin_example/main app/lib/ui_3/magazine/screens/home_screen.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/FAQ/faq.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/Newspaper%20and%20Kiddos/lib_kiddos/main.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/Newspaper%20and%20Kiddos/lib_news/main.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/premium/premium.dart';
import 'package:google_signin_example/widget/sign_up_widget.dart';
import 'detail_page.dart';
class HomePage1 extends StatefulWidget {
#override
_HomePage1State createState() => _HomePage1State();
}
class _HomePage1State extends State<HomePage1> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
child: Row(
children: <Widget>[
LeftWidget(),
Expanded(
child: RightWidget(),
)
],
),
),
);
}
}
class LeftWidget extends StatefulWidget {
#override
_LeftWidgetState createState() => _LeftWidgetState();
}
class _LeftWidgetState extends State<LeftWidget> with TickerProviderStateMixin {
List<String> _list = ["Home", "My profile", "Premium", "FAQ"];
List <Widget> _keys = [
HomePage1(), //These are the widgets from different classes.
LoggedInWidget(),
premium(),
faq(),
/*GlobalKey(), //This was available before I made the changes.
GlobalKey(),
GlobalKey(),
GlobalKey()*/
];
int checkIndex = 0;
Offset checkedPositionOffset = Offset(0, 0);
Offset lastCheckOffset = Offset(0, 0);
Offset animationOffset = Offset(0, 0);
Animation _animation;
AnimationController _animationController;
#override
void initState() {
checkIndex = _list.length - 1;
super.initState();
SchedulerBinding.instance.endOfFrame.then((value) {
calcuteCheckOffset();
addAnimation();
});
}
void calcuteCheckOffset() {
lastCheckOffset = checkedPositionOffset;
RenderBox renderBox = _keys[checkIndex].currentContext.findRenderObject(); //This is where the first error occurs.
Offset widgetOffset = renderBox.localToGlobal(Offset(0, 0));
Size widgetSise = renderBox.size;
checkedPositionOffset = Offset(widgetOffset.dx + widgetSise.width,
widgetOffset.dy + widgetSise.height);
}
#override
Widget build(BuildContext context) {
return Container(
child: Stack(
children: <Widget>[
Container(
width: 50,
decoration: BoxDecoration(
color: Color(0xff000000),
borderRadius: BorderRadius.circular(30),
),
child: Column(
children: _buildList(),
),
),
Positioned(
top: animationOffset.dy,
left: animationOffset.dx,
child: CustomPaint(
painter: CheckPointPainter(Offset(10, 0)),
),
)
],
),
);
}
List<Widget> _buildList() {
List<Widget> _widget_list = [];
_widget_list.add(Padding(
padding: EdgeInsets.only(
top: 50,
),
child: Icon(
Icons.settings,
color: Colors.white,
size: 30,
),
));
for (int i = 0; i < _list.length; i++) {
_widget_list.add(Expanded(
child: GestureDetector(
onTap: () {
indexChecked(i);
},
child: VerticalText(
_list[i],
_keys[i], //This is where the second error occurs.
checkIndex == i &&
(_animationController != null &&
_animationController.isCompleted))),
));
}
_widget_list.add(Padding(
padding: EdgeInsets.only(
top: 50,
bottom: 50,
),
child: Image(image: AssetImage('assets/images/Voix.png')),
));
return _widget_list;
}
void indexChecked(int i) {
if (checkIndex == i) return;
setState(() {
checkIndex = i;
calcuteCheckOffset();
addAnimation();
});
}
void addAnimation() {
_animationController =
AnimationController(duration: Duration(milliseconds: 300), vsync: this)
..addListener(() {
setState(() {
animationOffset =
Offset(checkedPositionOffset.dx, _animation.value);
});
});
_animation = Tween(begin: lastCheckOffset.dy, end: checkedPositionOffset.dy)
.animate(CurvedAnimation(
parent: _animationController, curve: Curves.easeInOutBack));
_animationController.forward();
}
}
class CheckPointPainter extends CustomPainter {
double pointRadius = 5;
double radius = 30;
Offset offset;
CheckPointPainter(this.offset);
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()..style = PaintingStyle.fill;
double startAngle = -math.pi / 2;
double sweepAngle = math.pi;
paint.color = Color(0xff000000);
canvas.drawArc(
Rect.fromCircle(center: Offset(offset.dx, offset.dy), radius: radius),
startAngle,
sweepAngle,
false,
paint);
paint.color = Color(0xffffffff);
canvas.drawCircle(
Offset(offset.dx - pointRadius / 2, offset.dy - pointRadius / 2),
pointRadius,
paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class VerticalText extends StatelessWidget {
String name;
bool checked;
GlobalKey globalKey;
VerticalText(this.name, this.globalKey, this.checked);
#override
Widget build(BuildContext context) {
return RotatedBox(
key: globalKey,
quarterTurns: 3,
child: Text(
name,
style: TextStyle(
color: checked ? Color(0xffffffff) : Colors.grey,
fontSize: 16,
),
),
);
}
}
class RightWidget extends StatefulWidget {
#override
_RightWidgetState createState() => _RightWidgetState();
}
class _RightWidgetState extends State<RightWidget>
with TickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 5);
}
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(
left: 15,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 50, left: 20),
child: Text(
"Voix Home",
style: TextStyle(
color: Colors.black,
fontSize: 25,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 15, left: 10),
child: SizedBox(
height: 30,
child: TabBar(
isScrollable: true,
unselectedLabelColor: Colors.black,
labelColor: Color(0xffffffff),
controller: _tabController,
indicator: BoxDecoration(
color: Color(0xff9e9e9e),
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
bottomLeft: Radius.circular(20),
),
),
tabs: <Widget>[
Tab(
text: "Flash",
),
Tab(
text: "Magazine",
),
Tab(
text: "Newspaper",
),
Tab(
text: "Kiddos",
),
Tab(
text: "Editorial",
),
],
),
),
),
Expanded(
child: TabBarView(
controller: _tabController,
children: <Widget>[
TravelWidget(),
HomeScreen(),
News(),
Kiddos(),
RightBody(),
// RightBody(),
],
),
)
],
),
);
}
}
class RightBody extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(
left: 15,
),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 20,
),
child: Text(
"Flash!",
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
),
Expanded(
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 220,
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
image: new DecorationImage(
image: new AssetImage('assets/images/bottom1.jpg'),
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
spreadRadius: 5,
blurRadius: 5,
offset: Offset(1, 2),
color: Color(0x33757575),
),
],
),
),
Container(
width: 220,
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(40),
boxShadow: [
BoxShadow(
spreadRadius: 5,
blurRadius: 5,
offset: Offset(1, 2),
color: Color(0x33757575),
),
],
),
),
],
),
),
],
),
);
}
}
class TravelWidget extends StatelessWidget {
List<TravelBean> _list = TravelBean.generateTravelBean();
#override
Widget build(BuildContext context) {
return PageView.builder(
controller: PageController(viewportFraction: 0.9),
itemBuilder: (context, index) {
var bean = _list[index];
return GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return DetailPage(bean);
}));
},
child: Hero(
tag: bean.url,
child: Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 30, right: 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.asset(
bean.url,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: 80,
left: 15,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Material(
color: Colors.transparent,
child: Text(
bean.location,
style: TextStyle(
color: Colors.black54,
fontSize: 15,
),
),
),
Material(
color: Colors.transparent,
child: Text(
bean.name,
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
),
],
),
),
Positioned(
bottom: 0,
right: 30,
child: Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.arrow_forward,
color: Colors.white,
size: 30,
),
),
)
],
),
),
);
},
itemCount: _list.length,
);
}
}
At the beginning, when I leave the list _keys to be of the type GlobalKey and don't comment out the following 4 GlobalKeys I get the output but the side menu bar won't work.
This is my application with GlobalKeys in place of those Widgets
I want those corresponding pages to display when clicked on. But that render object just switches between the options and the same page is displayed.
So kindly help me out.
PS : As said earlier I'm new to flutter, so kindly don't mistake me if I had something wrong.
I suggest you check about flutter state management, especially Mobx with Provider, it will be kind easier for you.

Flutter update data onClick at clicked index

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.

Categories

Resources