I'm making a program for calculations in flutter and when building the package, it throws me to the "debyg.dart" file and points to the line "throw FlutterError.fromParts(<DiagnosticsNode>[". So what should I do with this error. I'm still new to flutter, so I don't know much.
import 'package:flutter/material.dart';
import 'datchik/datchiki.dart';
import 'ThirdPage.dart';
import 'datchik/TCP10P.dart';
import 'datchik/TCP50P.dart';
import 'datchik/TCP100P.dart';
import 'datchik/TCP500P.dart';
import 'datchik/TCP1000P.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/',
routes: {
'/': (context) => const MyHome(),
'/datchiki': (context) => SecondPage(),
'/ThirdPage': (context) => ThirdPage(),
'/TCP10P': (context) => const TCP10P(),
'/TCP100P': (context) => const TCP100P(),
'/TCP50P': (context) => const TCP50P(),
'/TCP500P': (context) => const TCP500P(),
'/TCP1000P': (context) => const TCP1000P(),
},
),
);
}
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super (key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 214, 162, 248),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Главная страница",
style: TextStyle(fontSize: 20)),
TextButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/datchiki');
},
icon: const Icon(Icons.settings),
label: const Text('Датчики температур'),
),
ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/ThirdPage');
},
icon: const Icon(Icons.settings),
label: const Text('ТСП - 50П')
),
],
)
),
)
);
}
}
TCP-10P.dart The file in which the error appears
import 'package:flutter/material.dart';
import 'datchik/datchiki.dart';
import 'ThirdPage.dart';
import 'datchik/TCP10P.dart';
import 'datchik/TCP50P.dart';
import 'datchik/TCP100P.dart';
import 'datchik/TCP500P.dart';
import 'datchik/TCP1000P.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/',
routes: {
'/': (context) => const MyHome(),
'/datchiki': (context) => SecondPage(),
'/ThirdPage': (context) => ThirdPage(),
'/TCP10P': (context) => const TCP10P(),
'/TCP100P': (context) => const TCP100P(),
'/TCP50P': (context) => const TCP50P(),
'/TCP500P': (context) => const TCP500P(),
'/TCP1000P': (context) => const TCP1000P(),
},
),
);
}
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super (key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 214, 162, 248),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Главная страница",
style: TextStyle(fontSize: 20)),
TextButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/datchiki');
},
icon: const Icon(Icons.settings),
label: const Text('Датчики температур'),
),
ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/ThirdPage');
},
icon: const Icon(Icons.settings),
label: const Text('ТСП - 50П')
),
],
)
),
)
);
}
}
Debug.dart The file where it throws me
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('No Material widget found.'),
ErrorDescription(
'${context.widget.runtimeType} widgets require a Material '
'widget ancestor.\n'
'In Material Design, most widgets are conceptually "printed" on '
"a sheet of material. In Flutter's material library, that "
'material is represented by the Material widget. It is the '
'Material widget that renders ink splashes, for instance. '
'Because of this, many material library widgets require that '
'there be a Material widget in the tree above them.',
),
ErrorHint(
'To introduce a Material widget, you can either directly '
'include one, or use a widget that contains Material itself, '
'such as a Card, Dialog, Drawer, or Scaffold.',
),
...context.describeMissingAncestor(expectedAncestorType: Material),
]);
I tried changing the SizedBox parameters, but nothing worked. Maybe I just did it wrong
Related
i have tried in the following way but it is not working please tell me the solutions
import 'package:book_recommendation_app/about.dart';
import 'package:book_recommendation_app/home.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
void onTap(menuItem) {
switch (menuItem) {
case 'item1':
print('item1 clicked');
break;
case 'item2':
print('item2 clicked');
break;
case 'item3':
print('item3 clicked');
break;
}
}
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
var menuItems = <String>['item1', 'item2', 'item3'];
return MaterialApp(
title: 'Book Reccomendation Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Home'),
actions: <Widget>[
PopupMenuButton<String>(
onSelected: onTap,
itemBuilder: (BuildContext context) {
return menuItems.map((String choice) {
return PopupMenuItem<String>(
child: Text(choice),
value: choice,
);
}).toList();
})
],
),
body: searchBar(),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('Drawer Header'),
),
ListTile(
title: const Text('Item 1'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: const Text('About us'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AboutUs()),
);
Navigator.pop(context);
},
),
],
),
),
),
// home: const MyHomePage(title: 'Book Reccomendation Demo Home Page'),
);
}
}
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
var menuItems = <String>['item1', 'item2', 'item3'];
return MaterialApp(
title: 'Book Reccomendation Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Home'),
actions: <Widget>[
PopupMenuButton<String>(
onSelected: onTap,
itemBuilder: (BuildContext context) {
return menuItems.map((String choice) {
return PopupMenuItem<String>(
child: Text(choice),
value: choice,
);
}).toList();
})
],
),
body: searchBar(),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('Drawer Header'),
),
ListTile(
title: const Text('Item 1'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: const Text('About us'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AboutUs()),
);
Navigator.pop(context);
},
),
],
),
),
),
// home: const MyHomePage(title: 'Book Reccomendation Demo Home Page'),
);
}
}
Do not call Navigator.pop(context) immediately afther calling Navigator.push. Because for me it looks like your currently pushing to the next screen, but immediately popping again so that it will never be reached.
In this ListTile
ListTile(
title: const Text('About us'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AboutUs()),
);
Navigator.pop(context);
},
),
You use Navigator.Push(context,MaterialPageRout(builder: (context) => AboutUs()));
then you use Navegator.pop(context);
that means you push a new screen then you closed it and here is the problem
you need just to remove this line Navigator.pop(context);
You can use GetX too for navigate your pages in easier way if you don't want to go with MaterialPageRoute.
ListTile(
title: const Text('About us'),
onTap: () {
Get.to(AboutUs());
Navigator.pop(context);
},
),
Pop the drawer before pushing to new screen,
Like
Navigator.pop(context);
Navigator.push(context,
MaterialPageRoute(builder: (context) => AboutUs(),
),
);
ive basically got an rflutter alert that looks like this
Alert(
context: context,
title: "GAME OVER",
desc: "Youve got $correct/13, try again?",
buttons: [
DialogButton(
child: Text(
"COOL",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () => restart(),
width: 120,
)
],
).show();
but when i click on the area outside of the alert, it closes the alert. how do i make it such that the alert wont close when clicked outside?
i tried using "barrierDismissible" but got an error. perhaps is it even possible to make the alert not close when using the rflutter_alert package?
thank you
(i just started learning flutter and the class used rflutter_alert thats why im using it, is there a "best" way to present alerts?)
add barrierDismissible: false in showdialog default is true
showDialog<String>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => AlertDialog(
title: const Text('AlertDialog Title'),
content: const Text('AlertDialog description'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context, 'Cancel'),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK'),
),
],
),
);
SampleCode
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatelessWidget(),
),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => showDialog<String>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => AlertDialog(
title: const Text('AlertDialog Title'),
content: const Text('AlertDialog description'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context, 'Cancel'),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK'),
),
],
),
),
child: const Text('Show Dialog'),
);
}
}
Add this line to your code.
style: AlertStyle(isOverlayTapDismiss: false),
Full code then :
Alert(
context: context,
style: AlertStyle(isOverlayTapDismiss: false),
title: "GAME OVER",
desc: "Youve got $correct/13, try again?",
buttons: [
DialogButton(
child: Text(
"COOL",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () => restart(),
width: 120,
)
],
).show();
I am trying to create a shopping cart using provider and display the number of items currently in the cart on my homepage. When I create my cart icon with a text widget overlaid, the value being shown does not reflect the number of items in the cart.
Here is my code:
class OurShoppingBasketIcon extends StatelessWidget {
const OurShoppingBasketIcon({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ShoppingBasketScreen()),
);
},
child: Stack(
children: <Widget>[
new Icon(
Icons.shopping_cart_outlined,
color: Colors.white,
),
new Positioned(
right: 0,
child: new Container(
padding: EdgeInsets.all(1),
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(
minWidth: 12,
minHeight: 12,
),
child: Text(
context.read<ShoppingBasket>().items.length.toString(),
style: new TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
)
],
),
),
);
}
}
This is where the icon is implemented:
class OurHomePage extends StatefulWidget {
#override
_OurHomePageState createState() => _OurHomePageState();
}
class _OurHomePageState extends State<OurHomePage> {
#override
Widget build(BuildContext context) {
return Consumer<OurUser>(
builder: (_, user, __) {
return ChangeNotifierProvider<SignInViewModel>(
create: (_) => SignInViewModel(context.read),
builder: (_, child) {
return Scaffold(
appBar: AppBar(
title: Text("My app"),
actions: [
OurShoppingBasketIcon(),
IconButton(
icon: Icon(
Icons.logout,
color: Colors.white,
),
onPressed: () {
context.read<FirebaseAuthService>().signOut();
},
),
],
),
);
},
);
},
);
}
}
There are 2 items in the cart as of writing this:
But the icon on the homepage does not change:
Here is my main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MultiProvider(
providers: [
Provider(
create: (_) => FirebaseAuthService(),
),
StreamProvider<OurUser>(
create: (context) =>
context.read<FirebaseAuthService>().onAuthStateChanged),
ChangeNotifierProvider.value(
value: ShoppingBasket(),
),
],
child: MaterialApp(theme: OurTheme().buildTheme(), home: OurHomePage()),
),
);
}
perhaps if you watch for the value it will be updated dynamically:
context.watch<ShoppingBasket>().items.length.toString(), //<-- watch instead of read
The OurHomePage needs to be wrapped in the Provider<ShoppingBasket>.
return Provider<ShoppingBasket>(
create: (context) => ShoppingBasket(),
child: Consumer<OurUser>(
builder: (_, user, __) {
return ChangeNotifierProvider<SignInViewModel>(
create: (_) => SignInViewModel(context.read),
builder: (_, child) {
return Scaffold(
appBar: AppBar(
title: Text("My app"),
actions: [
OurShoppingBasketIcon(),
IconButton(
icon: Icon(
Icons.logout,
color: Colors.white,
),
onPressed: () {
context.read<FirebaseAuthService>().signOut();
},
),
],
),
),
);
},
);
I forgot to NotifyListeners() in my Change Notifier class:
class ShoppingBasket extends ChangeNotifier {
Map<String, SingleBasketItem> _items = {};
Map<String, SingleBasketItem> get items {
return {..._items};
}
void addItem(String id) {
_items.putIfAbsent(
id,
() => SingleBasketItem(id),
);
notifyListeners(); //HERE
}
I'm trying to build a collapse view after clicking an IconButton on my AppBar widget, I used ExpansionTile but nothing happens after I clicked the IconButton.
appBar: AppBar(
actions: <Widget>[
IconButton(
onPressed: () {
ExpansionTile(
title: Text(
"Settings",
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold
),
),
);
},
icon: Icon(Icons.settings),
),
],
),
Did I write the code right, or should I consider refactoring it. Thanks in advance!
Yes, you need to refactor your code because you cannot insert a widget into the widget tree this way directly from a function. I'm not sure of what you are trying to do, so I made two assumptions (1) You are trying to show a Expansion Tile in the app bar or (2) You want to show a Popup menu. Please see my code below to understand how you can achieve both.
import 'package:flutter/material.dart';
final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
title: 'Welcome to Flutter',
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget myWidget = Container(
child: const Text("Flutter"),
);
String myText = 'Hello, World!';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: myWidget, actions: [
IconButton(
onPressed: () async {
print(context);
showMenu(
context: context,
position: const RelativeRect.fromLTRB(110.0, 80.0, 0.0, 0.0),
items: ["One", "Two", "Three", "Four"]
.map(
(value) => PopupMenuItem<String>(
child: Text(value),
value: value,
),
)
.toList(),
elevation: 8.0,
);
},
icon: Icon(Icons.settings),
),
PopupMenuButton<int>(
onSelected: (selected) {
setState(
() {
myText = "You selected the menu number $selected";
},
);
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('First Item'),
),
const PopupMenuItem<int>(
value: 2,
child: Text('Second Item'),
),
const PopupMenuItem<int>(
value: 3,
child: Text('Thrid Item'),
),
const PopupMenuItem<int>(
value: 4,
child: Text('Fourth Item'),
),
],
)
]),
body: Center(
child: Text(myText, style: Theme.of(context).textTheme.headline4),
),
);
}
}
I have five items on the main screen, and what I want to do when one is pressed it goes to the corresponding page. Not sure exactly how to use the InkWell function to be able to push the tap from the first main page to the second page. .
Not sure if I am on the right track with the code below or need to go into another direction.
Main.dart
import 'package:flutter/material.dart';
import './food_catefgories.dart';
import './main_categories_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Made in Canada Stuff',
theme: ThemeData(
primarySwatch: Colors.blue,
canvasColor: Color.fromRGBO(225, 254, 229, 1),
textTheme: ThemeData.light().textTheme.copyWith(
body1: TextStyle(
color: Color.fromRGBO(20, 51, 51, 1),
),
body2: TextStyle(
color: Color.fromRGBO(20, 51, 51, 1),
),
title: TextStyle(
fontSize: 20,
fontFamily: 'RobotoCondensed',
fontWeight: FontWeight.bold,
)),
),
home: MainCategoriesScreen(),
initialRoute: '/spalsh',
routes: {
'/splash': (context) => MainCategoriesScreen(),
'/one': (context) => OneCategoriesScreen(),
'/two': (context) => TwoCategoriesScreen(),
'/three': (context) => ThreeCategoriesScreen(),
'/four': (context) => FourCategoriesScreen(),
'/five': (context) => FiveCategoriesScreen(),
},
);
}
}
main_categories_screen.dart
import 'package:flutter/material.dart';
import './category_item.dart';
class Category {
final String id;
final String title;
final Color color;
const Category({
this.id,
this.title,
this.color = Colors.orange,
});
}
const MAINCAT_CATEGORIES = const [
Category(
id: 'c1',
title: "ONE",
color: Colors.purple,
),
Category(
id: 'c2',
title: "TWO",
color: Colors.red,
),
Category(
id: 'c3',
title: "THREE",
color: Colors.blue,
),
];
class MainCategoriesScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Made title'),
),
body: GridView(
padding: const EdgeInsets.all(25),
children: MAINCAT_CATEGORIES
.map((catData) => CategoryItem(
catData.title,
catData.color,
),
)
.toList(),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
),
),
);
}
}
category_item.dart
import 'package:flutter/material.dart';
import './main_categories_screen.dart';
class CategoryItem extends StatelessWidget {
final String title;
final Color color;
CategoryItem(this.title, this.color);
void selectCategory(BuildContext ctx) {
Navigator.of(ctx).push(
MaterialPageRoute(
builder: (_) {
return MainCategoriesScreen();
},),);
}
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => selectCategory(context),
splashColor: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(15),
child: Container(
padding: const EdgeInsets.all(15),
child: Text(title,
style: Theme.of(context).textTheme.title,
),
decoration: BoxDecoration(gradient: LinearGradient(
colors: [
color.withOpacity(0.7),
color,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(15),
),
),
);
}
}
You can navigate from one screen to another and pass the data using Navigate class
For Example i'm using in my app.
Navigator.push(context,MaterialPageRoute(builder:
(context) => Home(userRole: role)),
ModalRoute.withName('/home'));
Navigator.push(context,MaterialPageRoute(builder:
(context) => Home(userRole: role))),
or
Navigator.pushNamed(context, '/first');
Make sure before using second line you have to declared all page in your MaterialApp like
initialRoute: '/spalsh',
routes: {
'/': (context) => LoginScreen(),
'/spalsh':(context)=>SplashScreen(),
'/first': (context) => FirstScreen(),
'/leave': (context) => ApplyLeave(),
'/bill': (context) => ApplyBill(),
'/contact': (context) => ContactUs(),
'/four': (context) => ScreenFour(),
'/five': (context) => ScreenFive(),
'/six': (context) => ScreenSix(),
'/seven': (context) => ScreenSeven(),
},
//Navigate to other page with class name and parameters
Navigator.push(
context, MaterialPageRoute(builder: (context) => FoodCategoriesScreen(title:"Items")));
//class name is FoodCategoriesScreen and the parameter is title to which we are assigning a value "Items".
//Navigator through routes that you have specified in your code (without parameters)
Navigator.pushNamed(context, '/food');