Theme Data not applying in inherited classes - flutter

I have declared a theme in main.dart , and it works fine as long as the context is used in main.dart but when I use Theme.of(context).primaryColor in the child class context doesn't pickup the theme.
Main.dart
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Expenso',
theme: ThemeData(
primarySwatch: Colors.green,
accentColor: Colors.amber
),
home: Expenso(),
);
}
}
class Expenso extends StatefulWidget {
#override
_ExpensoState createState() => _ExpensoState();
}
class _ExpensoState extends State<Expenso> {
final List<Transaction> _transactions=[
];
void _addTransaction(String txTitle,double txAmount)
{
final newTx=Transaction(
title: txTitle,
amount: txAmount,
id: DateTime.now().toString(),
date: DateTime.now()
);
setState(() {
_transactions.add(newTx);
});
}
void _startAddNewTransaction(BuildContext ctx) {
showModalBottomSheet(
context: ctx,
builder: (_) {
return GestureDetector(
onTap: () {},
child: NewTransaction(_addTransaction),
behavior: HitTestBehavior.opaque,
);
},
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor:Theme.of(context).primaryColor,
title: Text('Expenso'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () => _startAddNewTransaction(context),
)
],
),
body:SingleChildScrollView(
child: Column(
//mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
height: 50,
child: Card(
color: Colors.blue,
child: Text('chart')
)
),
TransactionList(_transactions)
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed:() => _startAddNewTransaction(context),
backgroundColor: Theme.of(context).accentColor,
),
)
);
}
}
transaction_list.dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../models/transaction.dart';
class TransactionList extends StatelessWidget {
final List<Transaction> tractn;
TransactionList(this.tractn);
#override
Widget build(BuildContext context) {
return Container(
height: 500,
child :tractn.isEmpty? Column(
children: <Widget>[
Text('No Transaction added yet'),
SizedBox(
height: 20,
),
Container(
height:300,
child: Image.asset('assets/Images/waiting.png',
fit: BoxFit.cover,),
)
],
): ListView.builder(
itemBuilder: (ctx,index){
return Card(
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
decoration: BoxDecoration(border: Border.all(
color: Theme.of(context).primaryColor,
width: 2,
style: BorderStyle.solid
)
),
padding: EdgeInsets.all(10),
child: Text(
'₹ ${tractn[index].amount.toStringAsFixed(2)}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic ,
fontSize: 20,
color: Colors.green,
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
tractn[index].title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Theme.of(context).primaryColor
),
),
Text(
DateFormat().format(tractn[index].date) ,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.grey
),),
Text(
tractn[index].id
)
],
)
],
),
);
},
itemCount: tractn.length,
)
);
}
}
Please guide me the way to implement the theme in inherited classes

I Agree with #Nolence comment.
If you are expecting to achieve the below result
Remove MaterialApp widget and make Scaffold as your primate return widget inside
class _ExpensoState
Sample Code:
import 'package:flutter/material.dart';
import 'package:flutter_app/Transaction.dart';
import 'transaction_list.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Expenso',
theme: ThemeData(
primarySwatch: Colors.green,
accentColor: Colors.amber
),
home: Expenso(),
);
}
}
class Expenso extends StatefulWidget {
#override
_ExpensoState createState() => _ExpensoState();
}
class _ExpensoState extends State<Expenso> {
final List<Transaction> _transactions=[
];
void _addTransaction(String txTitle,double txAmount)
{
final newTx=Transaction(
title: txTitle,
amount: txAmount,
id: DateTime.now().toString(),
date: DateTime.now()
);
setState(() {
_transactions.add(newTx);
});
}
void _startAddNewTransaction(BuildContext ctx) {
showModalBottomSheet(
context: ctx,
builder: (_) {
return GestureDetector(
onTap: () {},
child: NewTransaction(_addTransaction),
behavior: HitTestBehavior.opaque,
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor:Theme.of(context).primaryColor,
title: Text('Expenso'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () => _startAddNewTransaction(context),
)
],
),
body:SingleChildScrollView(
child: Column(
//mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
height: 50,
child: Card(
color: Colors.blue,
child: Text('chart')
)
),
TransactionList(_transactions)
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed:() => _startAddNewTransaction(context),
backgroundColor: Theme.of(context).accentColor,
),
);
}
}
If this is not what you wanted, please elaborate your question or comment below.

In the build method of your Expenso widget you define another MaterialApp, which creates its own default theme (different to your first theme). Remove that MaterialApp widget and it should work.

Related

It is not accepted to change the value in the Dropdown in the bottom sheet?

Flutter . It is not accepted to change the value in the Dropdown in the bottom sheet ?
I made all the changes and it didn't work !
Knowing that on a normal screen it works
please help me
class _AddPostState extends State<AddPost> {
List<DropdownMenuItem<String>> get itemse{
List<DropdownMenuItem<String>> menuItems = [
DropdownMenuItem(
value: '1',
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
SizedBox(width: 15,),
Icon(Icons.lock_outline,size: 19,),
SizedBox(width: 10,),
Text('Only me'),
],
),
),
),
DropdownMenuItem(
value: '2',
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
SizedBox(width: 15,),
Icon(Icons.group_rounded,size: 19,),
SizedBox(width: 10,),
Text('Friends'),
],
),
),
),
DropdownMenuItem(
value: '3',
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
SizedBox(width: 15,),
Icon(Icons.public,size: 19,),
SizedBox(width: 10,),
Text('Public'),
],
),
),
),
];
return menuItems;
}
String? selectedValue = '1';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
foregroundColor: Colors.black,
backgroundColor: Colors.white,
title: const Text('Add Post'),
),
body: Center(
child: ElevatedButton(
child: const Text('Open'),
onPressed: bottomSheet,
),
),
);
}
void bottomSheet(){
showCupertinoModalBottomSheet(
expand: true,
context: context,
backgroundColor: Colors.transparent,
builder: (context) =>Scaffold(
appBar: AppBar(backgroundColor: Colors.white,foregroundColor: Colors.black,),
body: Column(
children: [
DropdownButton(
value: selectedValue,
items: itemse,
onChanged: (y) {
setState(() {
selectedValue = y! as String;
});
},
)
],
),
),
);
}
}
Seven days, I searched for a solution to the problem and did not find the solution. Please help
From the code i see you are not using the StatefulBuilder which will rebuild the sheet and change your value. From the code that you provided i have just created and example for you which might help you.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<DropdownMenuItem<String>> get itemse {
List<DropdownMenuItem<String>> menuItems = [
DropdownMenuItem(
value: '1',
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
SizedBox(
width: 15,
),
Icon(
Icons.lock_outline,
size: 19,
),
SizedBox(
width: 10,
),
Text('Only me'),
],
),
),
),
DropdownMenuItem(
value: '2',
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
SizedBox(
width: 15,
),
Icon(
Icons.group_rounded,
size: 19,
),
SizedBox(
width: 10,
),
Text('Friends'),
],
),
),
),
DropdownMenuItem(
value: '3',
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
SizedBox(
width: 15,
),
Icon(
Icons.public,
size: 19,
),
SizedBox(
width: 10,
),
Text('Public'),
],
),
),
),
];
return menuItems;
}
String? selectedValue = '1';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
foregroundColor: Colors.black,
backgroundColor: Colors.white,
title: const Text('Add Post'),
),
body: Center(
child: ElevatedButton(
child: const Text('Open'),
onPressed: bottomSheet,
),
),
);
}
void bottomSheet() {
showCupertinoModalBottomSheet(
expand: true,
context: context,
backgroundColor: Colors.transparent,
builder: (context) =>
StatefulBuilder(builder: (BuildContext context, StateSetter setState /*You can rename this!*/) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
),
body: Column(
children: [
DropdownButton(
value: selectedValue,
items: itemse,
onChanged: (y) {
setState(() {
selectedValue = y! as String;
});
},
)
],
),
);
}),
);
}
}

How to access ThemeData from imported widgets

I can not use the ThemeData from the imported custom Widgets that I have imported from other files, I dont know if the BuildContext is changing or what. To all the widgets that are used in the main.dart file they can easily use Theme.of(context).colorScheme.primary but from imported widgets this does not work.
main.dart
import 'package:flutter/material.dart';
import 'widgets/expenses_list.dart';
import 'models/expenses_model.dart';
import 'widgets/new_expense.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData().copyWith(
colorScheme: ThemeData().colorScheme.copyWith(primary: Colors.red),
),
home: MyAppPage(),
);
}
}
class MyAppPage extends StatefulWidget {
#override
_MyAppPageState createState() => _MyAppPageState();
}
class _MyAppPageState extends State<MyAppPage> {
final List<ExpensesModel> _expensesObjectList = [
ExpensesModel(
id: DateTime.now().toString(),
name: "Shoes",
amount: 1200,
date: DateTime.now(),
),
ExpensesModel(
id: DateTime.now().toString(),
name: "Gun",
amount: 120000,
date: DateTime.now(),
),
];
void _addExpense(String exTitle, double exAmount) {
final _addExpenseObject = ExpensesModel(
id: DateTime.now().toString(),
name: exTitle,
amount: exAmount,
date: DateTime.now(),
);
setState(() {
_expensesObjectList.add(_addExpenseObject);
});
}
void _startAddNewExpense(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (bcontext) {
return NewExpense(_addExpense);
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.primary,
// HERE IT DOES WORK
title: Text(
"Expense App",
// style: Theme.of(context).textTheme.title,
),
actions: [
IconButton(
onPressed: () {
_startAddNewExpense(context);
},
icon: Icon(Icons.add),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
elevation: 5,
color: Theme.of(context).colorScheme.primary,
// HERE IT DOES WORK
child: Text("CHART!!"),
),
ExpensesList(_expensesObjectList), //THE IMPORTED WIDGET
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {
_startAddNewExpense(context);
},
child: Icon(Icons.add),
),
),
);
}
}
imported widget
import 'package:flutter/material.dart';
import '../models/expenses_model.dart';
class ExpensesList extends StatelessWidget {
final List<ExpensesModel> expensesObjectList;
ExpensesList(this.expensesObjectList);
#override
Widget build(BuildContext context) {
return Container(
height: 600,
child: ListView.builder(
itemBuilder: (context, index) {
return Card(
elevation: 5,
child: Row(
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.primary,
// HERE IT DOES NOT WORK
width: 2,
),
),
child: Text(
"PKR ${expensesObjectList[index].amount}",
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
// HERE IT DOES NOT WORK
fontWeight: FontWeight.bold,
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${expensesObjectList[index].name}",
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
DateTime.now().toString(),
style: TextStyle(
color: Colors.grey,
),
),
],
),
],
),
);
},
itemCount: expensesObjectList.length,
),
);
}
}
Screenshot of the app
as you can see the border and text aren't using the theme-defined color which is red.
You can access the ThemeData of your app by following.
Color color = Theme.of(context).primaryColor;
I think unnecessary "MaterialApp" of "build" in "class _MyAppPageState", like this.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.primary,
// HERE IT DOES WORK
title: Text(
"Expense App",
// style: Theme.of(context).textTheme.title,
),
actions: [
IconButton(
onPressed: () {
_startAddNewExpense(context);
},
icon: Icon(Icons.add),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
elevation: 5,
color: Theme.of(context).colorScheme.primary,
// HERE IT DOES WORK
child: Text("CHART!!"),
),
ExpensesList(_expensesObjectList), //THE IMPORTED WIDGET
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {
_startAddNewExpense(context);
},
child: Icon(Icons.add),
),
);
}
If you really need to "MaterialApp" of "class _MyAppPageState", I think you can add theme property, like this.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: Theme.of(context), // <- add this line.
home: Scaffold(
By the way, why won't you use primarySwatch?
How about this?
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.red,
),
home: MyAppPage(),
);
}
}

The method RegisterCustomer isn't defined for the class Dashboard when routing to another screen in flutter

I have Dashboard screen in lib directory. The register_customer.dart file is under customers subdirectory in lib folder. I have imported register_customer.dart in dashboard screen. However the RegisterCustomer class in register_customer.dart is not resolving. Here is my code:
lib/dashboard.dart
import 'package:flutter/material.dart';
import './customers/register_customer.dart';
class MyDashboard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: defaultBackgroundColor,
elevation: 0,
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: btnTextColor,
),
onPressed: () {
//navigate to the previous page
Navigator.pop(context);
},
),
//navabar title text text
title: Text('Dashboard'),
),
body: Center(
child: Column(
children: <Widget>[
Container(
margin: const EdgeInsets.all(20.0),
//color: Colors.amber[600],
width: 200.0,
height: 250.0,
child: ListView(
children: <Widget>[
GestureDetector(
child: ListTile(
title: Text(
'Register Customer',
style:
TextStyle(fontSize: 20, color: Color(0xffE06C19)),
),
leading: Icon(
Icons.user,
color: Colors.amber,
),
),
onTap: () {
**//this is where the error is being raised**
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RegisterCustomer()));
},
),
],
),
),
],
))),
);
}
}
lib/customers/register_customer.dart
import 'package:flutter/material.dart';
class RegisterCustomer extends StatefulWidget {
#override
_RegisterCustomerState createState() => _RegisterCustomerState();
}
String _first_name;
String _last_name;
class _RegisterCustomerState extends State<RegisterCustomer> {
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.purple[800],
accentColor: Colors.amber,
accentColorBrightness: Brightness.dark),
home: Scaffold(
appBar: AppBar(
title: Text(
'Register Customer',
style: TextStyle(fontSize: 20),
textAlign: TextAlign.center,
),
),
body: Container(
margin: EdgeInsets.all(12),
child: Form(
key: _formkey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 50,
),
RaisedButton(
color: Color(0xff980CF0),
textColor: Colors.white,
splashColor: Colors.grey,
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Text(
'Register',
style: TextStyle(
color: Colors.orangeAccent,
fontSize: 17,
),
),
onPressed: () {
if (!_formkey.currentState.validate()) {
return;
}
//submit data to the server
},
)
],
),
),
),
),
);
}
}
I am experiencing same issue with other routes. What am I doing wrong?
I think the import path is incorrect:
import 'package:projectname/customer/register_customer.dart
if the file is in lib/customer/register_customer.dart

Adding an Icon to a List using a button and actively updating UI using Provider state management

I want to add an Icon to a List following UI update using flutter Provider state Management.
I was successful to add an Icon using the floating button and confirm the result by printing the new List length. This ensures the addition of an Icon to a List but it does not update the UI for the new added Icon. Snippets are below
#override
_MedicalCosmeticsDetailsPageState createState() =>
_MedicalCosmeticsDetailsPageState();
}
class _MedicalCosmeticsDetailsPageState
extends State<MedicalCosmeticsDetailsPage> {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return ChangeNotifierProvider<GridIcons>(
create: (context) => GridIcons(),
child: SafeArea(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(color: Colors.purple),
title: Text(
'xyz',
style: TextStyle(color: Colors.purple),
),
backgroundColor: Colors.transparent,
elevation: size.width * 0.05,
actions: [
Padding(
padding: EdgeInsets.only(right: size.width * 0.01),
child: IconButton(
icon: Icon(
Icons.search,
),
onPressed: () {},
),
),
],
),
body: GridViewPage(),
floatingActionButton: Consumer<GridIcons>(
builder: (context, myIcons, _) {
return FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
print(myIcons.iconList.length);
myIcons.addIcon();
},
);
},
),
),
),
);
}
}
```//floating button for adding an ICON
```class GridIcons with ChangeNotifier {
List<IconData> iconList = [
Icons.ac_unit,
Icons.search,
Icons.arrow_back,
Icons.hdr_on_sharp,
];
addIcon<IconData>() {
iconList.add(Icons.sentiment_dissatisfied);
notifyListeners();
}
getIconList<IconData>() {
return iconList;
}
}
```//Function for icon addition
class GridViewPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
List _iconList = GridIcons().getIconList();
return ChangeNotifierProvider<GridIcons>(
create: (context) => GridIcons(),
child: Consumer<GridIcons>(
builder: (context, myIcon, child) {
return GridView.builder(
itemCount: _iconList.length,
padding: EdgeInsets.all(8.0),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250.0),
itemBuilder: (BuildContext context, int index) {
print('_buildGridViewBuilder $index');
return Card(
color: Colors.purple.shade300,
margin: EdgeInsets.all(8.0),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
_iconList[index],
size: 48.0,
color: Colors.purple.shade100,
),
Divider(),
Text(
'Index $index',
textAlign: TextAlign.center,
style: GoogleFonts.dmSans(
fontSize: 16,
color: Colors.white,
),
),
],
),
onTap: () {
print('Row: $index');
},
),
);
},
);
},
),
);
}
}
The icon doesn't appear in the UI although an icon is added to the Icon List.
You can copy paste run full code below
Step 1: In GridViewPage, you do not need ChangeNotifierProvider
Step 2: remove List _iconList = GridIcons().getIconList();
Step 3: use myIcon.iconList.length and myIcon.iconList[index]
code snippet
class GridViewPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
//List _iconList = GridIcons().getIconList();
return Consumer<GridIcons>(
builder: (context, myIcon, child) {
return GridView.builder(
itemCount: myIcon.iconList.length,
...
Icon(
myIcon.iconList[index],
size: 48.0,
working demo
full code
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
class MedicalCosmeticsDetailsPage extends StatefulWidget {
#override
_MedicalCosmeticsDetailsPageState createState() =>
_MedicalCosmeticsDetailsPageState();
}
class _MedicalCosmeticsDetailsPageState
extends State<MedicalCosmeticsDetailsPage> {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return ChangeNotifierProvider<GridIcons>(
create: (context) => GridIcons(),
child: SafeArea(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(color: Colors.purple),
title: Text(
'xyz',
style: TextStyle(color: Colors.purple),
),
backgroundColor: Colors.transparent,
elevation: size.width * 0.05,
actions: [
Padding(
padding: EdgeInsets.only(right: size.width * 0.01),
child: IconButton(
icon: Icon(
Icons.search,
),
onPressed: () {},
),
),
],
),
body: GridViewPage(),
floatingActionButton: Consumer<GridIcons>(
builder: (context, myIcons, _) {
return FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
print(myIcons.iconList.length);
myIcons.addIcon();
},
);
},
),
),
),
);
}
}
class GridIcons with ChangeNotifier {
List<IconData> iconList = [
Icons.ac_unit,
Icons.search,
Icons.arrow_back,
Icons.hdr_on_sharp,
];
addIcon<IconData>() {
iconList.add(Icons.sentiment_dissatisfied);
notifyListeners();
}
getIconList<IconData>() {
return iconList;
}
}
class GridViewPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
//List _iconList = GridIcons().getIconList();
return Consumer<GridIcons>(
builder: (context, myIcon, child) {
return GridView.builder(
itemCount: myIcon.iconList.length,
padding: EdgeInsets.all(8.0),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250.0),
itemBuilder: (BuildContext context, int index) {
print('_buildGridViewBuilder $index');
return Card(
color: Colors.purple.shade300,
margin: EdgeInsets.all(8.0),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
myIcon.iconList[index],
size: 48.0,
color: Colors.purple.shade100,
),
Divider(),
Text(
'Index $index',
textAlign: TextAlign.center,
style: GoogleFonts.dmSans(
fontSize: 16,
color: Colors.white,
),
),
],
),
onTap: () {
print('Row: $index');
},
),
);
},
);
},
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MedicalCosmeticsDetailsPage());
}
}

Search delegate , When I click on Search button it shows red screen with error child! =null

I create a search option by search delegate but When I click on search button it shows the red screen with this error "The following assertion was thrown building _SearchPage(dirty, dependencies: [_LocalizationsScope-[GlobalKey#69e74], _InheritedTheme], state: _SearchPageState#72bb6): 'package:flutter/src/widgets/basic.dart': Failed assertion: line 6938 pos 15: 'child != null': is not true.
import 'package:flutter/material.dart';
import 'package:grk_001/screen/main_screen.dart';
import 'widgets/entry_item.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:grk_001/screen/favourite_screen.dart';
import 'package:grk_001/Provider/Auth.dart';
import 'package:provider/provider.dart';
import 'package:grk_001/Provider/cart.dart';
import 'package:grk_001/widgets/badge.dart';
import 'package:grk_001/screen/cart_screen.dart';
import 'package:grk_001/widgets/drawer.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:grk_001/models/main_screen_categories_entry.dart';
class HomeScreen extends StatefulWidget {
static const String routename = 'homescreen';
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();
FirebaseUser Loggedinuser;
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
Future.delayed(Duration.zero).then((_) async {
await Provider.of<Auth>(context, listen: false).getcurrentuser();
});
super.didChangeDependencies();
}
#override
Widget build(BuildContext context) {
final devicesize = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
key: _scaffoldkey,
appBar: AppBar(
leading: IconButton(
onPressed: () {
_scaffoldkey.currentState.openDrawer();
},
icon: Icon(
Icons.list,
color: Colors.white,
size: 35.0,
),
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(50.0),
child: Container(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const SizedBox(
width: 10.0,
),
Expanded(
child: GestureDetector(
onTap: () {
_scaffoldkey.currentState.openEndDrawer();
},
child: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
height: 40.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5.0),
),
child: Text(
'Categories',
),
),
),
),
],
),
),
),
title: Text('HomeScreen'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch());
},
),
IconButton(
icon: Icon(
FontAwesomeIcons.heart,
size: 30.0,
),
tooltip: 'My Wish List',
onPressed: () {
Navigator.pushNamed(context, FavouriteScreen.routename);
},
),
IconButton(
icon: Icon(
Icons.notifications,
size: 30.0,
),
tooltip: 'My Notifications',
onPressed: () {},
),
Consumer<Cart>(
builder: (_, cartdata, ch) => Badge(
child: ch,
value: cartdata.itemcount.toString(),
),
child: IconButton(
onPressed: () {
Navigator.pushNamed(context, CartScreen.routename);
},
icon: Icon(
Icons.shopping_cart,
size: 40.0,
),
),
),
],
),
body: MainScreen(),
// body: CategoryScreen(),
endDrawer: Drawer(
child: Column(
children: <Widget>[
Container(
color: Color(0XFFFF4081),
height: devicesize.height * 0.10,
child: DrawerHeader(
margin: EdgeInsets.zero,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
Icons.apps,
color: Colors.white,
),
SizedBox(
width: 10.0,
),
Text(
'Categories',
style:
TextStyle(color: Colors.white, fontSize: 20.0),
),
],
),
)
// child: Text('Categories'),
),
),
Container(
height: devicesize.height * 0.85,
child: ListView.builder(
itemBuilder: (context, index) => EntryItem(data[index]),
itemCount: data.length,
),
)
],
),
),
drawer: Container(
width: devicesize.width * 0.65,
child: DrawerItem(devicesize, context),
),
),
);
}
}
class DataSearch extends SearchDelegate<String> {
final statelist = [
'Andaman and Nicobar Islands',
' Andhra Pradesh',
'Arunachal Pradesh',
'Assam',
'Bihar',
'Chandigarh ',
'Chhattisgarh',
'Dadra and Nagar Havel',
'Daman and Diu',
'Delhi',
'Goa',
'Gujrat',
'Haryana',
'Himachal Pradesh',
'Uttar Pradesh',
'Uttarakhand',
'West Bengal',
'Sikkim',
'Meghalya',
'Mizoram',
];
final recentlist = ['Modingar', 'Ghaziabad', 'Merrut', 'Hapur', 'Delhi'];
#override
List<Widget> buildActions(BuildContext context) {
// action for app bar
return [
IconButton(
onPressed: () {
query = "";
},
icon: Icon(Icons.clear),
)
];
}
#override
Widget buildLeading(BuildContext context) {
// leading icon on the left of the app bar
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
// TODO: implement buildResults
return Container(
height: 150.0,
child: Card(
color: Colors.red,
shape: StadiumBorder(),
child: Text(query),
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
final suggestionList = query.isEmpty
? recentlist
: statelist.where((element) => element.startsWith(query)).toList();
ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context);
},
title: RichText(
text: TextSpan(
text: suggestionList[index].substring(0, query.length),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: suggestionList[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
)),
itemCount: suggestionList.length,
);
}
}
You can copy paste run full code below
You need return keyword in buildSuggestions
You can return ListView.builder
code snippet
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
final suggestionList = query.isEmpty
? recentlist
: statelist.where((element) => element.startsWith(query)).toList();
return ListView.builder(
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title), actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch());
},
),
]),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class DataSearch extends SearchDelegate<String> {
final statelist = [
'Andaman and Nicobar Islands',
' Andhra Pradesh',
'Arunachal Pradesh',
'Assam',
'Bihar',
'Chandigarh ',
'Chhattisgarh',
'Dadra and Nagar Havel',
'Daman and Diu',
'Delhi',
'Goa',
'Gujrat',
'Haryana',
'Himachal Pradesh',
'Uttar Pradesh',
'Uttarakhand',
'West Bengal',
'Sikkim',
'Meghalya',
'Mizoram',
];
final recentlist = ['Modingar', 'Ghaziabad', 'Merrut', 'Hapur', 'Delhi'];
#override
List<Widget> buildActions(BuildContext context) {
// action for app bar
return [
IconButton(
onPressed: () {
query = "";
},
icon: Icon(Icons.clear),
)
];
}
#override
Widget buildLeading(BuildContext context) {
// leading icon on the left of the app bar
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
// TODO: implement buildResults
return Container(
height: 150.0,
child: Card(
color: Colors.red,
shape: StadiumBorder(),
child: Text(query),
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
final suggestionList = query.isEmpty
? recentlist
: statelist.where((element) => element.startsWith(query)).toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context);
},
title: RichText(
text: TextSpan(
text: suggestionList[index].substring(0, query.length),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: suggestionList[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
)),
itemCount: suggestionList.length,
);
}
}