TypeAhead different widgets flutter - flutter

I'm trying to create different widgets in TypeAhead suggestion depends on suggestion.subName.length
1. ListTile with a subTitle
2. ListTile without subTitle
TypeAhead(
...
itemBuilder: (context, suggestion) {
return ListTile(
dense: true,
title: AutoSizeText(
suggestion.primeName,
maxLines: 1,
overflow: TextOverflow.ellipsis,
minFontSize: 20,
),
subtitle: suggestion.subName.length == 0 ? null:AutoSizeText(
suggestion.subName.join(', '),
maxLines: 1,
overflow: TextOverflow.ellipsis,
minFontSize: 15,
),
);
},
...
But everything comes back with a subtitle.
What could cause that? Is it possible to make 2 different types of widgets in TypeAhead?

You can copy paste run full code below
I use the following example to simulate this case
You can return Container() not null
subtitle: suggestion.subName.length == 0 ? Container() : AutoSizeText(
or put condition in itemBuilder, for more complex condition you can use if
itemBuilder: (context, suggestion) {
return suggestion.subName.length == 0 ? ListTile(...) : ListTile(...);
working demo
full code
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter_typeahead/flutter_typeahead.dart';
class BackendService {
static Future<List> getSuggestions(String query) async {
await Future.delayed(Duration(seconds: 1));
return List.generate(3, (index) {
return {'name': query + index.toString(), 'price': Random().nextInt(100)};
});
}
}
class CitiesService {
static final List<String> cities = [
'Beirut',
'Damascus',
'San Fransisco',
'Rome',
'Los Angeles',
'Madrid',
'Bali',
'Barcelona',
'Paris',
'Bucharest',
'New York City',
'Philadelphia',
'Sydney',
];
static List<String> getSuggestions(String query) {
List<String> matches = List();
matches.addAll(cities);
matches.retainWhere((s) => s.toLowerCase().contains(query.toLowerCase()));
return matches;
}
}
class NavigationExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(32.0),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
TypeAheadField(
textFieldConfiguration: TextFieldConfiguration(
autofocus: true,
style: DefaultTextStyle.of(context)
.style
.copyWith(fontStyle: FontStyle.italic),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'What are you looking for?'),
),
suggestionsCallback: (pattern) async {
return await BackendService.getSuggestions(pattern);
},
itemBuilder: (context, suggestion) {
return ListTile(
leading: Icon(Icons.shopping_cart),
title: Text(suggestion['name']),
subtitle: suggestion['price'] < 20
? Container()
: Text('\$${suggestion['price']}'),
);
},
onSuggestionSelected: (suggestion) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ProductPage(product: suggestion)));
},
),
],
),
);
}
}
class ProductPage extends StatelessWidget {
final Map<String, dynamic> product;
ProductPage({this.product});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(50.0),
child: Column(
children: [
Text(
this.product['name'],
style: Theme.of(context).textTheme.headline,
),
Text(
this.product['price'].toString() + ' USD',
style: Theme.of(context).textTheme.subhead,
)
],
),
),
);
}
}
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),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
NavigationExample(),
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),
),
);
}
}

Related

How can I pass data from a TextFieldInput to another Page with Provider

I want to pass the Data (String) from a TextField to a second Page with Provider after I clicked the Button.
Here is my code
Update your name_provider class
class NameProvider extends ChangeNotifier {
String _name = "";
String get getName => _name;
saveName(String name) {
_name = name;
notifyListeners();
}
}
The name variable was made private to avoid getting wrong result while calling the function.
Now this edit was made to main.dart file
class _MyHomePageState extends State<MyHomePage> {
String name = "";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Please enter your name',
),
TextField(
onSubmitted: (value) {
setState(() {
Provider.of<NameProvider>(context).saveName(value);
});
},
onChanged: (value) {
setState(() {
name = value;
});
},
),
Text("Name: $name"),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SecondPage(),
),
);
},
child: const Text("To Second Page"),
),
],
),
),
),
);
}
}
Now getting name in SecondPage:
class SecondPage extends StatelessWidget {
const SecondPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Second Page"),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
"Name:",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
Text(
Provider.of<NameProvider>(context).getName,
style: TextStyle(fontSize: 32),
),
],
),
),
),
);
}
}
If there is some sort of expected string but got... error, replace getName with '${Provider.of<NameProvider>(context).getName}'
Let us know if this solution works
First of all, in the main.dart file at line 70, do this:
Provider.of<NameProvider>(context).saveName(name);
and then on the second page where you want to use this Provider.of<NameProvider>(context).name;
Here is the full working code.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderCheck extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => NameProvider(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Provider Problem'),
),
);
}
}
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> {
String name = "";
//it will store data in typed in textfield
final TextEditingController _textEditingController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Please enter your name',
),
TextField(
controller: _textEditingController,//texteditingcontroller set to textfield
onSubmitted: (value) {
setState(() {
name = value;
});
},
onChanged: (value) {
setState(() {
name = value;
});
},
),
Text("Name: $name"),
TextButton(
onPressed: () {
//saveName method called using provider and name saved.
Provider.of<NameProvider>(context, listen: false)
.saveName(_textEditingController.text);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SecondPage(),
),
);
},
child: const Text("To Second Page"),
),
],
),
),
),
);
}
}
class NameProvider extends ChangeNotifier {
String name = "";
String get getName => name;
//name1 value will set to name variable
saveName(String name1) {
name = name1;
notifyListeners();
}
}
class SecondPage extends StatelessWidget {
const SecondPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Second Page"),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//using provider, we can access the saved name
Text(
"Name:${Provider.of<NameProvider>(context, listen: false).getName}",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
Text(
//TODO: Name should be displayed here
"Name",
style: TextStyle(fontSize: 32),
),
],
),
),
),
);
}
}
if you prefer to use provider for that purpose,
edit your provider saveName Function to :
saveName(String _name) {
name = _name;
notifyListeners();
}
in SecondPage() add
your provider to the build method like this :
class SecondPage extends StatelessWidget {
const SecondPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final nameProvider = Provider.of< NameProvider>(context);
then get your string value by calling :
Text(
"Name: ${nameProvider.name}",
style : ....

Returns null value when using Localizations for multi-language system (Flutter, Dart)

I need to implement two languages in my application using packages (localizations).
In my application, there are 1 main view containing 4 tab views (Home(),Graph(),History(),GoalSetting), and 1 view(Record()) which are navigated by floating button.
My problem is, although AppLocalizations.of(context)!.registeredWord is correctly implemented at the main view and view from floating button, it returns "Null check operator used on a null value" at 4 tab views.
I am wondering how I can fix this.
Relating part of my code of main view is shown below. If you need additional information, please let me know.
import 'package:bottom_navy_bar/bottom_navy_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('ja', ''),
Locale('en', ''),
],
title: 'Flutter Demo',
home: MyHomePage(),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) :super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
PageController _pageController = PageController(initialPage: 0);
#override
void initState() {
super.initState();
_pageController = PageController();
}
int _currentIndex = 0;
List<Widget> viewList = [
Home(),
const Graph(),
History(),
GoalSetting()
];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: viewList[_currentIndex],
floatingActionButtonLocation:
FloatingActionButtonLocation.endFloat,
floatingActionButton: SizedBox(
width: 60,
child: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Record(),
));
},
child: const Icon(Icons.add),
)),
bottomNavigationBar: BottomNavyBar(
selectedIndex: _currentIndex,
showElevation: true,
containerHeight: 70,
itemCornerRadius: 24,
curve: Curves.easeIn,
onItemSelected: (index) => setState(() => _currentIndex = index),
items: <BottomNavyBarItem>[
BottomNavyBarItem(
icon: const Icon(Icons.home),
title: Text(AppLocalizations.of(context)!.home), //OK
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: const Icon(Icons.show_chart),
title: Text(AppLocalizations.of(context)!.graph), //OK
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: const Icon(Icons.history),
title: Text(
AppLocalizations.of(context)!.history,
),
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: const Icon(Icons.flag),
title: Text(AppLocalizations.of(context)!.goals), //OK
activeColor: Colors.blueGrey,
textAlign: TextAlign.center,
),
],
),
),
);
}
}
Additionally, One example code of tab views is shown below.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';
import 'package:stylerecord/Model/goal.dart';
import 'Model/record.dart';
import 'Model/sqlite.dart';
import 'main.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return WatchBoxBuilder(
box: boxList[0],
builder: (context, recordHiveBox) {
return WatchBoxBuilder(
box: boxList[1],
builder: (context, goalHiveBox) {
return Consumer<GoalData>( //The relevant error-causing widget
builder: (context, goalData, child) {
return Consumer<RecordData>(
builder: (context, recordData, child) {
RecordHive lastRecord =
recordHiveBox.getAt(recordHiveBox.length - 1);
return Scaffold(
appBar: AppBar(
title: Text('StyleRecord'),
backgroundColor: Colors.blueGrey[900]),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 20.0,
fontFamily: 'MPLUSRounded1c'),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Text(AppLocalizations.of(context)!.part), //Error("this was the stack")
Text(AppLocalizations.of(context)!.weight),
........
Text(AppLocalizations.of(context)!.ankle),
Padding(
padding: const EdgeInsets.all(16))
])),
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 25.0,
fontFamily: 'MPLUSRounded1c'),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Text(AppLocalizations.of(context)!
// .lasTime),
Text(
'${lastRecord.measurement[0]} kg'),
...
Text(
'${lastRecord.measurement[8]} cm'),
Padding(
padding: const EdgeInsets.all(20))
])),
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 20.0,
fontFamily: 'MPLUSRounded1c'),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
// Text(AppLocalizations.of(context)!
// .toGoal),
(goalHiveBox.isEmpty)
? Text(
L10n.of(context)!
.noData)
: goalData.TextDif(
recordHiveBox.getAt(
recordHiveBox.length - 1),
goalHiveBox.getAt(0),
0),
...
(goalHiveBox.isEmpty)
? Text(
L10n.of(context)!
.noData)
: goalData.TextDif(
recordHiveBox.getAt(
recordHiveBox.length - 1),
goalHiveBox.getAt(0),
8),
Padding(
padding: const EdgeInsets.all(16))
]))
]),
);
},
);
},
);
});
});
}
}

How to use Flutter GetX Sidebar

How can I implement the design in the image (sidebar and navigation menu) in Flutter using GetX? similarly to Tabs on the web.
This is a example, maybe it can help you:
import 'package:flutter/material.dart';
import '../../routes/app_pages.dart';
import 'package:get/get.dart';
class SideBar extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
DrawerHeader(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Center(
child: Icon(
Icons.person,
color: Colors.white,
size: 50.0,
),
),
Center(
child: Text(
"Vakup",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
],
),
decoration: BoxDecoration(
color: Colors.blueAccent,
),
),
ListTile(
leading: Icon(Icons.read_more),
title: Text('Leer datos'),
onTap: () {
if (Get.currentRoute == Routes.HOME) {
Get.back();
} else {
Get.toNamed(Routes.HOME);
}
},
),
ListTile(
leading: Icon(Icons.pets),
title: Text('Registrar animal'),
onTap: () {
if (Get.currentRoute == Routes.NEWANIMAL) {
Get.back();
} else {
Get.toNamed(Routes.NEWANIMAL);
}
},
),
ListTile(
leading: Icon(Icons.list_alt),
title: Text('Lista movimientos'),
onTap: () {
if (Get.currentRoute == Routes.MOVEMENTS) {
Get.back();
} else {
//Get.to
Get.toNamed(Routes.MOVEMENTS);
}
},
),
ListTile(
leading: Icon(Icons.list),
title: Text('Lista animales'),
onTap: () {
if (Get.currentRoute == Routes.LISTOFANIMALS) {
Get.back();
} else {
Get.toNamed(Routes.LISTOFANIMALS);
}
},
),
ListTile(
leading: Icon(Icons.edit),
title: Text('Grabar datos'),
onTap: () {
if (Get.currentRoute == Routes.GRABADO) {
Get.back();
} else {
Get.toNamed(Routes.GRABADO);
}
},
),
ListTile(
leading: Icon(Icons.bluetooth),
title: Text('Conexion BT'),
onTap: () {
if (Get.currentRoute == Routes.CONEXIONBT) {
Get.back();
} else {
Get.toNamed(Routes.CONEXIONBT);
}
},
),
ListTile(
leading: Icon(Icons.picture_as_pdf),
title: Text('Exportar Datos'),
onTap: () {
if (Get.currentRoute == Routes.EXPORT) {
Get.back();
} else {
Get.toNamed(Routes.EXPORT);
}
},
),
ListTile(
leading: Icon(Icons.recent_actors_rounded),
title: Text('Acerca de'),
onTap: () {
if (Get.currentRoute == Routes.ACERCA) {
Get.back();
} else {
Get.toNamed(Routes.ACERCA);
}
},
),
],
),
);
}
}
And the home part is:
import 'package:vakuprfid/app/modules/widgets/side_bar.dart';//import widget
class HomeView extends GetView<HomeController> {
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: SideBar(),
body: ...
);
}
}
This is the result:
For the main content put all the different view into a list and put it into PageView. And create a custom navigator and put these two widget into a Row:
Controller:
class SettingsController extends GetxController {
final PageController pageController =
PageController(initialPage: 1, keepPage: true);
}
Sidebar:
class MySideNavigation extends StatefulWidget {
MySideNavigation({Key? key}) : super(key: key);
#override
State<MySideNavigation> createState() => _MySideNavigationState();
}
class _MySideNavigationState extends State<MySideNavigation> {
#override
Widget build(BuildContext context) {
final SettingsController c = Get.find();
return NavigationRail(
selectedIndex: c.selectedViewIndex.value,
onDestinationSelected: (value) async {
setState(() {
c.selectedViewIndex(value);
c.pageController.jumpToPage(
value,
// duration: Duration(milliseconds: 500), curve: Curves.decelerate
);
});
},
labelType: NavigationRailLabelType.selected,
destinations: const <NavigationRailDestination>[
NavigationRailDestination(
icon: Icon(Icons.map_outlined),
selectedIcon: Icon(Icons.map_rounded),
label: Text(
'نقشه ها',
style: TextStyle(fontSize: 14, fontFamily: 'Vazir'),
),
),
NavigationRailDestination(
icon: Icon(Icons.map_outlined),
selectedIcon: Icon(Icons.map_rounded),
label: Text(
'نقشه ها',
style: TextStyle(fontSize: 14, fontFamily: 'Vazir'),
),
),
NavigationRailDestination(
icon: Icon(Icons.person_outline),
selectedIcon: Icon(Icons.person),
label: Text(
'پروفایل',
style: TextStyle(fontSize: 14, fontFamily: 'Vazir'),
),
),
],
);
}
}
GotFatherView:
class GodFatherView extends StatelessWidget {
GodFatherView({Key? key}) : super(key: key);
final PageStorageBucket bucket = PageStorageBucket();
final SettingsController c = Get.find();
List<Widget> pages = [
const KeepAlivePage(Page1()),
KeepAlivePage(Page2()),
const KeepAlivePage(Page3()),
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: [
MySideNavigation(),
Expanded(
child: PageView(
controller: c.pageController,
children: pages,
),
)
],
));
}
}
tap on below link to open screenshot: I don't have enough reputation to post image :))))))
Screeshot
Give a special attention to the sidebar navigator in MySideNavigation class:
NavigationRail(
selectedIndex: c.selectedViewIndex.value,
onDestinationSelected: (value) async {
setState(() {
c.pageController.jumpToPage(value);
});
},
When user tap on each NavigationRailDestination ,onDestinationSelected function will be called with an index. The index are representing the index of the destination view. Example: When user on [Page1() -> index:0] tab on the second NavigationRailDestination the index inside of function is 1, so you can use the PageController to navigate into [Page2() -> index:1].
Attention, Attention, More Attention:
If you don't like to lose the state(I mean when u navigate to another view and back to previous view don't rebuild it again). Sometimes we need to keep the state of widget, we change something, write something into a text field and etc. If you don't wrap it with this widget all the data will be loosed(or you can save it through another way).
Wrap your widget with this Widget see the GodFather View I wrap all pages with KeepAlivePage, In this widget I extend State of the widget with 'AutomaticKeepAliveClientMixin' and override its value bool get wantKeepAlive => true; .
import 'package:flutter/material.dart';
class KeepAlivePage extends StatefulWidget {
const KeepAlivePage(this.child, {Key? key}) : super(key: key);
final child;
#override
State<KeepAlivePage> createState() => _KeepAlivePageState();
}
class _KeepAlivePageState extends State<KeepAlivePage>
with AutomaticKeepAliveClientMixin {
#override
Widget build(BuildContext context) {
super.build(context);
return widget.child;
}
#override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
it's easy,just let your right conent use GetMaterialApp and the route change is render right concent, then left sidler is a component warp your menuslider,
last control you left slider menuchange index.
show my code
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(dessignWidth, dessignHeight),
builder: () => BarcodeKeyboardListener(
onBarcodeScanned: (String codeValue) {},
child: Material(
child: MaterialApp(
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [
Locale('zh', 'CH'),
Locale('en', 'US'),
],
home: Row(
children: [
Material(
child: SliderMenu(),
),
Expanded(
child: GetMaterialApp(
debugShowCheckedModeBanner: false,
enableLog: true,
navigatorKey: Get.key,
routingCallback: RouteChangeMiddleWare.observer,
logWriterCallback: Logger.write,
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
unknownRoute: AppPages.unknownRoute,
builder: EasyLoading.init(),
onInit: () =>
{logger.v('Global.CONFIG', AppConfig)}))
],
)),
)));
}```
hope to help you;

String not updating with changeNotifierProvider

model class:
Venue with ChangeNotifier{
String id;
update(String venueId) {
id = venueId;
notifyListeners();
}
}
Trying to get the id value like so:
Widget _buildContents(BuildContext context) {
final venue = Provider.of<Venue>(context);
final id = venue.id;
print('##########'); //// trying to get the the id here.
}
My id is supposed to be updated in the onTap callback of a dropDownButton:
DropdownButton(
....
items: venues.map((venue) {
return DropdownMenuItem<String>(
onTap: () {
venue.update(venue.id);
},
value: venue.name,
child: Text(
venue.name,
style: TextStyle(fontSize: 28),
),
);
}).toList(),
.....
)
And the Provider.. is above the widgets:
MultiProvider(providers: [
ChangeNotifierProvider<Venue>(create: (_) => Venue()),
], child: HomePage());
Something is wrong..help!?
You can copy paste run full code below
You can use DropdownButton<Venue> and call venue.update in onChanged
code snippet
DropdownButton<Venue>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (Venue newValue) {
setState(() {
dropdownValue = newValue;
venue.update(newValue.id);
});
},
items: venues.map((venue) {
return DropdownMenuItem<Venue>(
value: venue,
child: Text(
venue.name,
style: TextStyle(fontSize: 28),
),
);
}).toList()
working demo output
I/flutter (27988): ########## 1
I/flutter (27988): ########## 2
working demo
full code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Venue with ChangeNotifier {
String id;
String name;
update(String venueId) {
id = venueId;
notifyListeners();
}
Venue({this.id, this.name});
}
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: MultiProvider(providers: [
ChangeNotifierProvider<Venue>(create: (_) => Venue()),
], child: HomePage()),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Venue dropdownValue;
List<Venue> venues = [
Venue(id: "1", name: "name1"),
Venue(id: "2", name: "name2"),
Venue(id: "3", name: "name3"),
];
#override
Widget build(BuildContext context) {
final venue = Provider.of<Venue>(context);
final id = venue.id;
print('########## $id');
return Scaffold(
appBar: AppBar(
title: Text("demo"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<Venue>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (Venue newValue) {
setState(() {
dropdownValue = newValue;
venue.update(newValue.id);
});
},
items: venues.map((venue) {
return DropdownMenuItem<Venue>(
value: venue,
child: Text(
venue.name,
style: TextStyle(fontSize: 28),
),
);
}).toList(),
),
],
),
),
);
}
}

Can someone check my Dart code and tell me where I'm making mistake in returning data from my screen as a ListView

I am stuck here for the past 20 days in returning data in my app from the other screen. I'm new to programming and need help. I've been searching through all the internet to find an answer related to my query but nothing is helping though. I ask my fellow SO guys to please help.
You can look at the entire code which I've made open here.
My code:
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(30),
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.blue,
),
onPressed: () async {
final newList = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FavoriteList(),
),
);
setState(() {
return ListView.builder(
itemCount: newList.length,
itemBuilder: (context, index){
return Container(
child: Text('item: $newList'),
);
},
);
});
},
)
],
),
);
}
}
The screen where Navigator.pop() is used:
final Set saved = Set();
class FavoriteList extends StatefulWidget {
#override
_FavoriteListState createState() => _FavoriteListState();
}
class _FavoriteListState extends State<FavoriteList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Favorites!'),
centerTitle: true,
backgroundColor: Colors.red),
body: SafeArea(
child: ListView.builder(
itemCount: 53,
itemBuilder: (context, index) {
return CheckboxListTile(
activeColor: Colors.red,
checkColor: Colors.white,
value: saved.contains(index),
onChanged: (val) {
setState(() {
// isChecked = val; // changed
// if(val == true){ // changed
// __saved.add(context); // changed
// } else{ // changed
// __saved.remove(context); // changed
// } // changed
if (val == true) {
saved.add(index);
} else {
saved.remove(index);
}
});
},
title: Row(
children: <Widget>[
Image.asset('lib/images/${images[index]}'),
SizedBox(
width: 10,
),
Text(nameOfSite[index]),
],
),
);
},
),
),
floatingActionButton: FloatingActionButton(
foregroundColor: Colors.red,
child: Icon(Icons.check),
onPressed: () {
Navigator.pop<Set>(context, saved);
},
),
);
}
}
Here is the SecondPage and FavoriteList that I made
import 'package:flutter/material.dart';
import 'package:aioapp2/lists.dart';
Set<int> favorites = {};
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return Stack(
fit: StackFit.expand,
children: <Widget>[
_getFavoriteList(),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: FloatingActionButton(
child: Icon(
Icons.edit,
color: Colors.blue,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditFavorites(),
),
).then((updatedFavorites) {
if (updatedFavorites != null)
setState(() {
favorites = updatedFavorites;
});
});
},
),
),
)
],
);
}
Widget _getFavoriteList() {
if (favorites?.isNotEmpty == true)
return _FavoriteList();
else
return _EmptyFavoriteList();
}
}
class _EmptyFavoriteList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Add Your Favorite Sites Here!❤',
style: TextStyle(color: Colors.white),
),
Icon(
Icons.favorite,
size: 150,
color: Colors.blue[100],
),
],
),
),
),
),
],
);
}
}
class _FavoriteList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: favorites.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('lib/images/${images[index]}'),
),
title: Text(nameOfSite[favorites.elementAt(index)]),
);
},
);
}
}
//Its FavoriteList Page. I changed the name
class EditFavorites extends StatefulWidget {
#override
_EditFavoritesState createState() => _EditFavoritesState();
}
class _EditFavoritesState extends State<EditFavorites> {
final _editableFavorites = <int>{};
#override
void initState() {
_editableFavorites.addAll(favorites);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Favorites!'),
centerTitle: true,
backgroundColor: Colors.red,
actions: <Widget>[
IconButton(
icon: Icon(Icons.done),
onPressed: () {
Navigator.pop<Set>(context, _editableFavorites);
},
)
],
),
//backgroundColor: Colors.indigo,
body: SafeArea(
child: ListView.builder(
itemCount: nameOfSite.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('lib/images/${images[index]}'),
),
title: Text(nameOfSite[index]),
trailing: IconButton(
icon: _editableFavorites.contains(index)
? Icon(
Icons.favorite,
color: Colors.red,
)
: Icon(
Icons.favorite_border,
color: Colors.grey,
),
onPressed: () {
setState(() {
if (_editableFavorites.contains(index))
_editableFavorites.remove(index);
else
_editableFavorites.add(index);
});
},
),
);
},
),
),
);
}
}
Just replace secondtab.dart with this code.
You can copy paste run full code below
You have to move out return ListView to the same layer with FloatingActionButton
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SecondPage(),
);
}
}
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),
),
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.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
Set newList = {};
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(30),
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
ListView.builder(
itemCount: newList.length,
itemBuilder: (context, index) {
return Container(
child: Text('item: ${newList.elementAt(index)}'),
);
},
),
FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.blue,
),
onPressed: () async {
newList = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FavoriteList(),
),
);
setState(() {});
},
)
],
),
);
}
}
final Set saved = Set();
class FavoriteList extends StatefulWidget {
#override
_FavoriteListState createState() => _FavoriteListState();
}
class _FavoriteListState extends State<FavoriteList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Favorites!'),
centerTitle: true,
backgroundColor: Colors.red),
body: SafeArea(
child: ListView.builder(
itemCount: 53,
itemBuilder: (context, index) {
return CheckboxListTile(
activeColor: Colors.red,
checkColor: Colors.white,
value: saved.contains(index),
onChanged: (val) {
setState(() {
// isChecked = val; // changed
// if(val == true){ // changed
// __saved.add(context); // changed
// } else{ // changed
// __saved.remove(context); // changed
// } // changed
if (val == true) {
saved.add(index);
} else {
saved.remove(index);
}
});
},
title: Row(
children: <Widget>[
//Image.asset('lib/images/${images[index]}'),
SizedBox(
width: 10,
),
Text('nameOfSite[index]'),
],
),
);
},
),
),
floatingActionButton: FloatingActionButton(
foregroundColor: Colors.red,
child: Icon(Icons.check),
onPressed: () {
Navigator.pop<Set>(context, saved);
},
),
);
}
}