Flutter: using nested navigator - flutter

I have a page that divides the screen into left (CheckOutPage) and right (MyFoodOrder()):
class TakeOrderPage extends StatefulWidget {
#override
_TakeOrderPageState createState() => _TakeOrderPageState();
}
class _TakeOrderPageState extends State<TakeOrderPage> {
#override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Expanded(flex: 4, child: CheckOutPage()),
VerticalDivider(),
Expanded(flex: 6, child: MyFoodOrder()),
],
);
}
}
In MyFoodOrder, I have a widget that builds the food items using FoodCard:
Widget buildFoodList() {
return Expanded(
child: GridView.count(
//itemCount: foods.length,
childAspectRatio: 3.0,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
crossAxisCount: 2,
controller: _controller,
physics: BouncingScrollPhysics(),
//children: foods.map((food) {
// return FoodCard(food);
//}).toList(),
children: [for (var food in Level1) if ((food.foodType == MyFoodTypes[value])) FoodCard(food)].toList(),
),
);
}
Inside FoodCard, I have a widget that has an InkWell that can move to another page when tapped for selecting options. At the moment, the new page ChooseOptions() will occupy the whole screen:
Widget buildPriceInfo() {
ConfirmAction action;
return Padding(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'\$ ${food.price}',
style: titleStyle,
),
Card(
margin: EdgeInsets.only(right: 0),
shape: roundedRectangle4,
color: mainColor,
child: InkWell(
onTap: IsAvailable() ? () async {
remark = ''; //cancel any selected taste
if (food.options.length != 0) {
if (food.options.containsKey('2')) {
action = await _showTasteDialog(food.index);
}
if (food.options.containsKey('1')) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChooseOptions(food)),
);
}
else
addItemToCard();
}
else
addItemToCard();
} : (){},
splashColor: Colors.white70,
customBorder: roundedRectangle4,
child: Icon(Icons.add, size: 30,),
),
)
],
),
);
}
I want to modify it so that the new page of ChooseOptions only occupies the area of MyFoodOrder() instead of the whole screen. I read that nested navigator is the solution but I couldn't work it out after reading some of the examples online. Grateful if more explicit guidance or help can be provided.
Many thanks!

Wrap your MyFoodOrder with Navigator, set the routes, and assign a Navigation Key to it.
static final navigatorKey = GlobalKey<NavigatorState>();
Then use the Navigation Key to changing the routing.
navigatorKey.currentState.pushNamed("Your route");

Related

Flutter GetX Re-Initialise GetX Controller Reset GetX Controller, Reset GetX Controller Values

I am learning Flutter GetX to my own and stuck on a point. Actually I want to know why onInit method of GetX Controlled is not calling whenever I revisit that page/dialog again.
Suppose that I have dialog with a simple TextField, a Listview the TextField is used for searching the listview. When the User enters any filter key inside the text field, the listview will be filtered.
Here is the Sample Dialog:
import 'package:flutter/material.dart';
import 'package:flutter_base_sample/util/apptheme/colors/app_colors.dart';
import 'package:flutter_base_sample/util/apptheme/styles/text_styles_util.dart';
import 'package:flutter_base_sample/util/commons/app_util.dart';
import 'package:flutter_base_sample/util/widgets/alert/controllers/country_finder_alert_controller.dart';
import 'package:flutter_base_sample/util/widgets/marquee/marquee_widget.dart';
import 'package:flutter_base_sample/util/widgets/textfields/app_text_field.dart';
import 'package:get/get.dart';
class SampleDialogWidget extends StatelessWidget {
final CountryFinderAlertController controller = Get.put(CountryFinderAlertController(),permanent: true);
#override
Widget build(BuildContext context) {
return Dialog(
insetPadding: AppUtil.dialogPadding(context),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
elevation: 0.0,
backgroundColor: Colors.white,
child: dialogContent(context),
);
}
Widget dialogContent(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Text(
"Hello Heading",
style: TextStyleUtil.quickSandBold(context, fontSize: 16, color: Colors.blue),
textAlign: TextAlign.center,
),
SizedBox(
height: 20,
),
Expanded(
child: SingleChildScrollView(
child: Container(
height: AppUtil.deviceHeight(context),
padding: EdgeInsetsDirectional.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Hello Text1"),
SizedBox(
height: 10,
),
getSearchField(context),
SizedBox(
height: 5,
),
Expanded(
child: Obx(()=> getFavoritesListView(context)),
)
],
),
),
),
),
SizedBox(
height: 20,
),
Container(
margin: EdgeInsetsDirectional.only(start: 20,end: 20),
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
overlayColor: MaterialStateProperty.all<Color>(Colors.red),
// splashFactory: NoSplash.splashFactory,
elevation: MaterialStateProperty.all(0.5),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
return AppColors.instance.black.withOpacity(0.1);
} else {
return Colors.blue; // Use the component's default.
}
},
),
),
child: Text(
"Hello Footer",
style: TextStyleUtil.quickSandBold(context, fontSize: 16, color: Colors.yellow),
textAlign: TextAlign.center,
),
),
)
],
);
}
Widget getFavoritesListView(BuildContext context) {
if (controller.favoritesList.length > 0) {
return ListView.separated(
shrinkWrap: true,
itemCount: controller.favoritesList.length,
itemBuilder: (BuildContext context, int index) => _topupFavoriteContent(context, index),
separatorBuilder: (context, index) {
return Divider(
indent: 15,
endIndent: 15,
);
},
);
} else {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
"No Data Found!",
textAlign: TextAlign.center,
),
SizedBox(
height: 20,
),
],
),
);
}
}
Widget _topupFavoriteContent(BuildContext context, int index) {
final item = controller.favoritesList[index];
return InkWell(
onTap: () {
Get.back(result:item);
// AppUtil.pop(context: context, valueToReturn: item);
},
child: getChildItems(context, index));
}
Widget getChildItems(BuildContext context, int index) {
return Directionality(textDirection: TextDirection.ltr, child: getContactNumberAndNameHolder(context, index));
}
Widget getContactNumberAndNameHolder(BuildContext context, int index) {
final item = controller.favoritesList[index];
return Container(
padding: EdgeInsetsDirectional.only(start: 20, end: 20, top: 20, bottom: 10),
child: Column(
children: [
Row(
// crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Align(
alignment: AlignmentDirectional.centerStart,
child: Text(
item.name ?? "",
style: TextStyleUtil.quickSandBold(context, fontSize: 15, color: AppColors.instance.black),
),
),
),
SizedBox(
width: 5,
),
Container(),
Align(
alignment: AlignmentDirectional.centerEnd,
child: MarqueeWidget(
child: Text(
item.dialCode ?? "",
style: TextStyleUtil.quickSandBold(context, fontSize: 15, color: Colors.blue),
),
),
),
],
)
],
),
);
}
Widget getSearchField(
BuildContext context,
) {
return Container(
margin: EdgeInsetsDirectional.only(start: 20, end: 20, top: 20),
child: Row(
children: [
Expanded(
child: AppTextField(
onChanged: (String text) {
controller.performSearchOnForFavoriteContact(text);
},
isPasswordField: false,
keyboardType: TextInputType.text,
suffixIconClickCallBack: () {},
),
)
],
));
}
}
and here is the GetX Controller:
class CountryFinderAlertController extends GetxController {
TextEditingController countrySearchFieldEditController = TextEditingController();
RxList<CountryHelperModel> favoritesList;
RxList<CountryHelperModel> originalList;
#override
void onInit() {
super.onInit();
debugPrint("Hello222");
favoritesList = <CountryHelperModel>[].obs;
originalList = <CountryHelperModel>[].obs;
}
#override
void onReady() {
super.onReady();
debugPrint("Hello111");
originalList.addAll(JSONHelperUtil.getCountries());
addAllCountries();
}
#override
void dispose() {
super.dispose();
countrySearchFieldEditController.dispose();
}
#override
void onClose() {
super.onClose();
}
void performSearchOnForFavoriteContact(String filterKey) {
if (filterKey != null && filterKey.isNotEmpty) {
List<CountryHelperModel> filteredFavoritesList = [];
debugPrint("filterKey" + filterKey);
originalList.forEach((element) {
if (element.name.toLowerCase().contains(filterKey.toLowerCase()) ||
element.countryCode.toLowerCase().contains(filterKey.toLowerCase()) ||
element.dialCode.toLowerCase().contains(filterKey.toLowerCase())) {
filteredFavoritesList.add(element);
}
});
if (filteredFavoritesList.isNotEmpty) {
favoritesList.clear();
favoritesList.addAll(filteredFavoritesList);
} else {
favoritesList.clear();
}
} else {
//reset the list
addAllCountries();
}
}
void addAllCountries() {
favoritesList.clear();
favoritesList.addAll(originalList);
}
}
So what I want is to load fresh data each time when I open this dialog. For now, if user will search for any country and close the dialog and then if reopen it the user will see the older search results.
In simple means how can GetX Controller be Reset/Destroyed or reinitialised !
Thanks in advance
So the answer to this question from me is that the Flutter pub GetX do provide a way to delete any initialised controller. Let's suppose that we only have a controller that needs to call an API in its onInit() method, every time the user will land on that specific view controller suppose!
So the solution to this problem is to just call:
Get.delete<YourControllerName>();
The thing that when it should get called is important. For me the clean way to do it, when I goto a new page I register a value to return/result callback as:
Get.to(()=>YourWidgetView());
to
Get.to(()=>YourWidgetView()).then((value) => Get.delete<YourControllerName>());
So whenever the user will leave your Widget View will delete the respected controller. In this way when the user will come again to the same widget view, the controller will re-initialised and all the controller values will be reset.
If anyone does have any better solution can share with the dev community.
Thanks
I believe it's because of ,permanent: true
Try leaving that out.
Considering this is dialog, there's no need to inject the controller using Get.put() method. Instead try this, using this approach every time we call SimpleDialogWidget, its controller will be created and disposed of when Get.back() will be called.
Step 1 : Extend your SimpleDialogWidget with GetView<CountryFinderAlertController>
class SampleDialogWidget extends GetView<CountryFinderAlertController> {...}
Step 2 : Wrap your actual widget inside Getx
class SampleDialogWidget extends GetView<CountryFinderAlertController> {
#override
Widget build(BuildContext context) {
return GetX<CountryFinderAlertController>( //Here it is
init : CountryFinderAlertController(), // like this
builder: (controller) => Dialog(
insetPadding: AppUtil.dialogPadding(context),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
elevation: 0.0,
backgroundColor: Colors.white,
child: dialogContent(controller, context), // Also, pass the controller to dialogContent function
);
);
}
}
That will solve your problem.
Disposing your resources always come after disposing super resources. So change the following
#override
void dispose() {
super.dispose();
countrySearchFieldEditController.dispose();
}
with
#override
void dispose() {
countrySearchFieldEditController.dispose();
super.dispose();
}
If it still not works, please attach the binding file code as well.
Controller won't get disposed:
class SampleDialogWidget extends StatelessWidget {
final CountryFinderAlertController controller = Get.put(CountryFinderAlertController(),permanent: true);
#override
Widget build(BuildContext context) {
return Dialog(
Instantiation & registration (Get.put(...)) should not be done as a field.
Otherwise, the registration of controller is attached to LandingScreen, not MainScreen. And Controller will only get disposed when LandingScreen is disposed. Since that's the home Widget in the code above, disposal only happens upon app exit.
Fix: Move Get.put to the build() method.
class SampleDialogWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
final CountryFinderAlertController controller = Get.put(CountryFinderAlertController());
return Dialog(
Others said to initialize the controller, but sometimes there are other ways. I recommend using GetWidget instead StatelessWidget
class SampleDialogWidget extends GetWidget<CountryFinderAlertController> {...}
and 'your_any_screen_bindings.dart' file seems like
class YourAnyScreenBindings implements Bindings {
#override
void dependencies() {
Get.put(YourAnyScreenCtrl());
Get.create(() => CountryFinderAlertController());
}
}
and 'your_routes.dart' file will be...
List<GetPage<dynamic>> getPages = [
GetPage(
name: '/your_any_screen',
page: () => YourAnyScreen(),
binding: YourAnyScreenBindings(),
),
]
Now your dialog widget will be paired with a FRESH controller every time.

gestureEvent or PointerEvent on longPressed DialogBox

How to add tap or longpress (any gestureDector event) on longpressed DialogBox
clicking on icons on popop after showing that, can we swipe on icons and getting action like with click?
hear i'am, using "OverlyEntery" to show dialog, iam using overlyEntry because it will keep the gesture longpress event, it's work fine when longpress show the Dialog and disappear when longpressEnd event occurred, but the problem is after open a dialog Box,
in Dialog box i was not able to add any event, hear i want like instagram image preview.
Thank you.
import 'package:flutter/material.dart';
class Explore extends StatelessWidget {
Explore({Key? key}) : super(key: key);
OverlayEntry _popUp({required String url}) {
return OverlayEntry(
builder: (context) => Dialog(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: double.infinity,
padding: EdgeInsets.all(10.0),
color: Colors.black,
child: Center(
child: Text(
"Trip Body name",
style: TextStyle(color: Colors.white),
)),
),
Image.asset(url),
Container(
color: Colors.black,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onLongPress: () {
print("press1");
},
onLongPressCancel: () {
print("press2");
},
onLongPressDown: (e) {
print("press3");
},
onLongPressMoveUpdate: (d) {
print("press4");
},
child: Container(
child: const Icon(
Icons.favorite,
color: Colors.white,
)),
),
Icon(Icons.save)
],
),
)
],
)));
}
OverlayEntry? _popUpDialog;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: StaggeredGridView.countBuilder(
// controller: _scrollController,
crossAxisCount: 2,
itemCount: 50,
itemBuilder: (BuildContext context, int index) => InkWell(
onTap: () {
},
child: GestureDetector(
// behavior: HitTestBehavior.deferToChild,
onLongPress: () {
_popUpDialog = _popUp(
url: 'assets/images/a' +
((index < 15)
? index.toString()
: index > 20
? '3'
: (index - 10).toString()) +
'.jpeg');
Overlay.of(context)!.insert(_popUpDialog!);
},
onLongPressEnd: (d) {
_popUpDialog!.remove();
},
child: Image.asset((
'assets/images/a' +
((index < 15)
? index.toString()
: index > 20
? '3'
: (index - 10).toString()) +
'.jpeg'
)),
),
staggeredTileBuilder: (int index) => StaggeredTile.count(
1, isForReel(index: index) ? 1.5 : 1), // 2,11,23,30,44
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
),
),
)
]
)
);
}
}
Try to add Gesture Detecter on body of DialogBox rather than SubViews.

Flutter - Expandable - How to keep the panel expanded when changing the state

I am using the expandable package (https://pub.dev/packages/expandable), and when I call the setState () method when taping on a checkbox the expandable panel closes during the widget tree reconstruction.
When I call setState () I tell the controller to keep the panel expanded expController.expanded = true, but that doesn't work.
I researched and it seems to me that the solution would be to use a key, but my tests did not work.
Can someone help me? I need to change the state of the checkbox, but keep the panel expanded.
Here is an sample from my code:
class ExpandableCard extends StatefulWidget {
ExpandableCard({Key key}) : super(key: key);
#override
_ExpandableCardState createState() => _ExpandableCardState();
}
class _ExpandableCardState extends State<ExpandableCard> {
var _value = false;
#override
Widget build(BuildContext context) {
ExpandableController expController =
new ExpandableController(initialExpanded: false);
return ExpandableNotifier(
controller: expController,
child: Padding(
padding: const EdgeInsets.all(2),
child: Card(
clipBehavior: Clip.antiAlias,
child: Column(
children: <Widget>[
ScrollOnExpand(
scrollOnExpand: true,
scrollOnCollapse: false,
child: ExpandablePanel(
theme: const ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
tapBodyToCollapse: false,
tapHeaderToExpand: true,
tapBodyToExpand: true,
hasIcon: true,
),
header: Padding(
padding: EdgeInsets.all(10),
child: Text('HEADER'),
),
collapsed: Padding(
padding: EdgeInsets.only(left: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('collapsed'),
],
),
),
expanded: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
for (var _ in Iterable.generate(3))
Padding(
padding: EdgeInsets.only(left: 2, bottom: 2),
child: Row(
children: [
Checkbox(
value: _value,
onChanged: (bool value) {
setState(() {
this._value = value;
expController.expanded = true;
});
},
),
Text('Checkbox'),
],
),
),
],
),
builder: (_, collapsed, expanded) {
return Padding(
padding:
EdgeInsets.only(left: 10, right: 10, bottom: 10),
child: Expandable(
collapsed: collapsed,
expanded: expanded,
theme: const ExpandableThemeData(crossFadePoint: 0),
),
);
},
),
),
],
),
),
));
}
}
Sorry it is very late but as i was using expandable in my app then i came to know that:
You can do this by first making an ExpandableController, then assiging its initialExpanded a static bool isOpened (It needs to be static because the bool that we are assigning to initialExpanded should be present before the construction of this ExpandableController). Then in initState(), you have to add an addListener to it that will change the value of isOpened. So now whenever you will tap on the expandable, the listener will listen and will change the value of isOpened and now when the tree widget will reconstruct this isOpened variable will have the current state of the Expandable.
static bool isOpened=false;
ExpandableController additionalInfoController=ExpandableController(
initialExpanded: isOpened,
);
// do this in initState
additionalInfoController.addListener(()
{
isOpened=!isOpened;
});
//Then assign this controller to the controller of ExpandablePanel like this
ExpandablePanel(
controller: additionalInfoController,
);

I have a parent widget that contains multiple child widgets which each include a checkbox. How can I check every checkbox from the parent widget?

I have a parent widget that draws multiple child widgets using a listview. There is a checkbox within each of these child widgets. I am trying to implement a "select all" button in the parent widget which checks all of the children's checkboxes, but I'm having a hard time figuring out how to accomplish this.
Here is my parent widget:
class OrderDisplay extends StatefulWidget {
static const routeName = '/orderDisplay';
//final Order order;
//const OrderDisplay(this.order);
#override
OrderDisplayState createState() {
return OrderDisplayState();
}
}
class OrderDisplayState extends State<OrderDisplay> {
bool preChecked = false;
double total = 0;
List<OrderedItem> itemsToPayFor = [];
#override
Widget build(BuildContext context) {
final OrderDisplayArguments args =
ModalRoute.of(context).settings.arguments;
return Scaffold(
backgroundColor: MyColors.backgroundColor,
body: SafeArea(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
physics: ScrollPhysics(),
child: Container(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Text(args.order.restaurantName,
style: MyTextStyles.headingStyle),
ListView.separated(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: args.order.orderedItems.length,
itemBuilder: (context, index) {
return FoodOrderNode(
preChecked, args.order.orderedItems[index],
onCheckedChanged: (isChecked) {
isChecked
? setState(() {
itemsToPayFor.add(
args.order.orderedItems[index]);
})
: setState(() {
itemsToPayFor.remove(
args.order.orderedItems[index]);
});
});
},
separatorBuilder: (context, index) =>
MyDividers.MyDivider)
],
)),
),
),
MyDividers.MyDivider,
Container(
height: 140,
color: MyColors.backgroundColor,
child: Row(children: [
Expanded(
flex: 5,
child: Column(
children: [
Expanded(flex: 2, child: SizedBox()),
Expanded(
flex: 6,
child: SelectAllButton(() {
print("SELECT ALL");
setState(() {
preChecked = true;
});
})),
Expanded(flex: 2, child: SizedBox())
],
)),
Expanded(
flex: 5,
child: Column(
children: [
Expanded(flex: 1, child: SizedBox()),
Expanded(
flex: 8,
child: PayNowButton(() {
print("PAY NOW");
},
double.parse(itemsToPayFor
.fold(0, (t, e) => t + e.itemPrice)
.toStringAsFixed(
2)))),
Expanded(flex: 1, child: SizedBox())
],
))
]))
],
)));
}
}
And here is FoodOrderNode:
typedef void SelectedCallback(bool isChecked);
class FoodOrderNode extends StatefulWidget {
final bool preChecked;
final OrderedItem item;
final SelectedCallback onCheckedChanged;
const FoodOrderNode(this.preChecked, this.item,
{#required this.onCheckedChanged});
#override
FoodOrderNodeState createState() {
return FoodOrderNodeState();
}
}
class FoodOrderNodeState extends State<FoodOrderNode> {
bool isChecked = false;
bool isSplitSelected = false;
#override
Widget build(BuildContext context) {
isChecked = widget.preChecked;
return Container(
height: 80,
padding: EdgeInsets.only(left: 15, right: 15),
decoration: BoxDecoration(
color: MyColors.nodeBackgroundColor,
),
child: Row(
children: [
Expanded(
flex: 1,
child: CircularCheckBox(
value: isChecked,
checkColor: Colors.white,
activeColor: Colors.blue,
autofocus: false,
onChanged: (bool value) {
print("Change to val: $value");
widget.onCheckedChanged(value);
setState(() {
isChecked = value;
});
},
)),
Expanded(
flex: 7,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.only(bottom: 5, left: 40),
child: Text(
widget.item.itemName,
style: TextStyle(fontSize: 18, color: Colors.black),
textAlign: TextAlign.left,
maxLines: 2,
overflow: TextOverflow.ellipsis,
)),
Container(
padding: EdgeInsets.only(left: 40),
child: Text(
"\$${widget.item.itemPrice}",
style:
TextStyle(fontSize: 16, color: MyColors.labelColor),
))
],
),
),
Expanded(
flex: 2,
child: isSplitSelected
? SplitButtonSelected(() {
setState(() {
isSplitSelected = false;
});
})
: SplitButtonUnselected(() {
setState(() {
isSplitSelected = true;
});
}))
],
),
);
}
}
I have tried creating a "preChecked" argument for FoodOrderNode and then using setState from the parent widget, however, that hasn't worked out. I have also tried using keys, but I couldn't figure out how to get those working for this either. Thank you, and let me know if you'd like any more relevant code.
Just put a global checkbox above the list items and give it isAllChecked (bool) on its value so when it will be checked set the state to isAllChecked => true and then in child checkboxes check for condition if isAllChecked is true then mark as true or checked.
GlobalCheckbox(
onChanged(value){
setState(()
{
isAllChecked==value;
});
}
);
ChildCheckBox(
value: isAllChecked ? true : false
)
this might help you:)

Flutter display Listview when button pressed

List<ServicesMensCollection> menServicesList = []
..add(ServicesMensCollection('ihdgfstfyergjergdshf', 'janik', 10))
..add(ServicesMensCollection('ihdgfstfyergjerg', 'janik', 10))
..add(ServicesMensCollection('ihdgfstfyergjerg', 'janik', 10))
..add(ServicesMensCollection('ihdgfstfyergjergdf', 'janik', 10))
bool _value2 = false;
void _value2Changed(bool value) => setState(() => _value2 = value);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
body: new Container(
decoration: new BoxDecoration(color: const Color(0xFFEAEAEA)),
child: Padding(
padding: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
child: Column(
children: <Widget>[
servicesCategory(),
],),),)); }
Widget servicesButton() {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: () {listView();},
child: Text('Mens'),),
RaisedButton(
onPressed: () {listView();},
child: Text('Womens')),
RaisedButton(
onPressed: () {listView();},
child: Text('Childrens'),
)]); }
Widget listView(){
return ListView.builder(
itemCount: menServicesList.length,
itemBuilder: (BuildContext context, int index) {
return list(index); },);
}
Widget list(int index){
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(menServicesList[index].name),
Text(menServicesList[index].name),
Checkbox(onChanged:_value2Changed,
value: _value2,
)],),);
}}
I am implementing listview with checkbox in my project.I have 3 buttons which is created in a row.I want to display the list when the button is clicked.Here the issue is listview is not at all visible for me.I had implemented the same example in android but i don't know how to do this in flutter.
Try this. This is a sample screen which you can refer for your implementation.
In this there are 3 sample list which are being replaced to main list on selection, you can add a function which will sort the list based on selection (so no need to have multiple lists)
import 'package:flutter/material.dart';
/*
These are the sample list for demo
*/
List<ItemVO> mainList = List();
List<ItemVO> sampleMenList = [
ItemVO("1", "Mens 1"),
ItemVO("2", "Mens 2"),
ItemVO("3", "Mens 3")
];
List<ItemVO> sampleWomenList = [
ItemVO("1", "Women 1"),
ItemVO("2", "Women 2"),
ItemVO("3", "Women 3")
];
List<ItemVO> sampleKidsList = [
ItemVO("1", "kids 1"),
ItemVO("2", "kids 2"),
ItemVO("3", "kids 3")
];
class TestScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _TestScreen();
}
}
class _TestScreen extends State<TestScreen> {
#override
void initState() {
super.initState();
mainList.addAll(sampleMenList);
}
#override
Widget build(BuildContext context) {
return Material(
child: Stack(
children: <Widget>[
ListView.builder(
itemBuilder: (BuildContext context, index) {
return getCard(index);
},
itemCount: mainList.length,
),
Container(
margin: EdgeInsets.only(bottom: 20),
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () {
mainList.clear();
setState(() {
mainList.addAll(sampleMenList);
});
},
heroTag: "btn1",
child: Text("Mens"),
),
FloatingActionButton(
onPressed: () {
mainList.clear();
setState(() {
mainList.addAll(sampleWomenList);
});
},
heroTag: "btn2",
child: Text("Women"),
),
FloatingActionButton(
onPressed: () {
mainList.clear();
setState(() {
mainList.addAll(sampleKidsList);
});
},
heroTag: "btn3",
child: Text("Kids"),
)
],
),
),
],
),
);
}
/*
Get the card item for a list
*/
getCard(int position) {
ItemVO model = mainList[position];
return Card(
child: Container(
height: 50,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"ID:: "+model._id,
style: TextStyle(fontSize: 18, color: Colors.black),
),
Padding(padding: EdgeInsets.only(left: 5,right: 5)),
Text(
"Name:: "+model._name,
style: TextStyle(fontSize: 18, color: Colors.black),
)
],
),
),
margin: EdgeInsets.all(10),
);
}
}
/*
Custom model
i.e. for itemList
*/
class ItemVO {
String _id, _name;
String get id => _id;
set id(String value) {
_id = value;
}
get name => _name;
set name(value) {
_name = value;
}
ItemVO(this._id, this._name);
}
In your code you didn't added ListView in widget, so it will not show any list, so try adding ListView in widget and then change the list data and try it.
I think You have 2 choices on how to tackle your problem.
Preload the listViews and set their visibility to gone / invisible
Try to play around with the code from this blog