In short I am trying to pass the title of the button from my input screen to my calculator model and once inside the calculator model, a value will be returned based on the button selected. However, currently my calculator is preforming the task WITHOUT waiting for the title of the button. Any ideas on how I can await the button title? I tried future, async, and await functionality but still couldn't get it to work properly.
Input Screen
class InputScreen extends StatefulWidget {
#override
_InputScreenState createState() =>
_InputScreenState();
}
class _InputScreenState
extends State<InputScreen> {
final MyButton selected = MyButton(title3: 'Female', title4: 'Male', title5: 'Unknown');
#override
void dispose() {
super.dispose();
selected.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Column(
children: <Widget>[
ClipPath(
clipper: MyClipper(),
child: Container(
height: 250,
width: double.infinity,
decoration: BoxDecoration(
gradient: kHeaderGradient,
image: DecorationImage(
image: AssetImage('images/virus.png'),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
Navigator.pop(context);
}),
],
title: Text(
'Gender Multiplier',
style: kHeaderTextStyle,
),
backgroundColor: Colors.transparent,
elevation: 0.0,
),
],
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
ValueListenableBuilder<Option>(
valueListenable: selected,
builder: (context, option, _) => MakeButtons(
num0: 3,
num1: 6,
makeButtonWidth: MediaQuery.of(context).size.width * 0.45,
selected: option,
onChanged: (newOption) => selected.option = newOption,
),
),
RoundedButton(
title: 'Calculate',
onPressed: () {
Calculator calc;
calc = Calculator(
buttonTitle: selected.title,
);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultsScreen(
genderMultiplier: calc.calculate(),
),
),
);
},
),
],
),
],
),
);
}
}
class MyClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
var path = Path();
path.lineTo(0, size.height - 80);
path.quadraticBezierTo(
size.width / 2, size.height, size.width, size.height - 80);
path.lineTo(size.width, 0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}
Calculator model
class Calculator {
Calculator({
this.buttonTitle,
});
String buttonTitle;
double _genderModifier
String calculate() {
double getMultiplier() {
if (buttonTitle == 'Male') {return 2;}
else if (buttonTitle == 'Female') {return 1;}
else {return 0;}
}
if (getMultiplier() == 0) {return 'Does not work';} else {
_genderModifier = 10 * getMultipler();
return _genderModifier.toStringAsFixed(1);}
}
}
Results Screen
class ResultsScreen extends StatelessWidget {
ResultsScreen({
#required this.genderMultiplier,
});
final String genderMultiplier;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('CALCULATOR'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
padding: EdgeInsets.all(15),
alignment: Alignment.bottomLeft,
child: Text(
'Your Result',
),
),
ReuseableCard(
bgColor: kGreyBackgroundColor,
cardChild: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
genderMultiplier,
),
],
),
),
RoundedButton(
title: 'Re-Calc',
onPressed: () {
Navigator.pop(context);
},
)
],
),
);
}
}
You are using a widget called ValueListenableBuilder and it seems you do not really know what it does. And I cannot really help you with the specifics of your code there because I don't know what a MyButton is or what MakeButtons does. It looks complicated.
But as a matter of fact you don't need to know how that widget works, because I don't see any reason why you would use it in your code in the first place.
If in doubt, go with simple. Simple and working is way better than complicated and not working.
Take your calculator class, this is all it really does:
String calculate(String buttonTitle) {
if (buttonTitle == 'Male') return 20.toStringAsFixed(1);
if (buttonTitle == 'Female') return 10.toStringAsFixed(1);
return 'Does not work';
}
Try to not over-complicate things.
If you need a three-state selection, why not go with radio buttons? Simple, easy, tutorials all over the internet. That should work. Or use ToggleButtons.
Related
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.
I am building a webapp with flutter where I want to add google sign in. The button itself works fine, but whatever I try, it just takes up my whole screen. I tried putting the button in the class in a container and putting it in a sizedbox on the page I actually want to use it on, and limiting the size of the button itself. This is my first time with flutter web, so I'd really like to know why this is happening.
Here is my code for the button:
class GoogleButton extends StatefulWidget {
#override
_GoogleButtonState createState() => _GoogleButtonState();
final DatabaseRepo databaseRepo;
final InitRepo initRepo;
GoogleButton(this.databaseRepo, this.initRepo);
}
class _GoogleButtonState extends State<GoogleButton> {
bool _isProcessing = false;
#override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height / 10,
child: FlatButton(
height: MediaQuery.of(context).size.height / 10,
onPressed: () async {
setState(() {
_isProcessing = true;
});
await signInWithGoogle().then((result) {
print(result);
Navigator.of(context).pop();
Navigator.of(context).push(
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) =>
MainPage(widget.databaseRepo, widget.initRepo),
),
);
}).catchError((error) {
print('Registration Error: $error');
});
setState(() {
_isProcessing = false;
});
},
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: _isProcessing
? CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(
Colors.blueGrey,
),
)
: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text(
'Bejelentkezés',
style: TextStyle(
fontSize: 20,
color: Colors.blueGrey,
),
))
]))),
);
}
}
Just to be on the safe side, here is the code for the page itself:
import 'package:flutter/material.dart';
import 'package:foci_dev/repo/database_repo.dart';
import 'package:foci_dev/repo/init_repo.dart';
import 'package:foci_dev/ui/google_button.dart';
class SignInPage extends StatelessWidget {
final DatabaseRepo databaseRepo;
final InitRepo initRepo;
SignInPage(this.databaseRepo, this.initRepo);
#override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[800],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 5,
width: MediaQuery.of(context).size.height / 5,
child: Column(
children: [
Image(image: AssetImage('lib/assets/icon.png')),
Container(
height: MediaQuery.of(context).size.height / 10,
child: ButtonTheme(
height: 20,
child:
GoogleButton(this.databaseRepo, this.initRepo))),
],
)),
],
),
);
}
}
Thank you very much for your help, I really don't know what to do.
I am using the package
country_code_picker: ^1.4.0
https://pub.dev/packages/country_code_picker#-installing-tab-
with flutter 1.17.3
Which is pretty much one of the only country code picker packages. But I have one serious problem an I don't have a clue what it could be.
When I run this code
import 'package:flutter/material.dart';
import 'package:country_code_picker/country_code_picker.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
App();
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: TestWidget(),
);
}
}
class TestWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(body: _buildCountryPicker(context));
}
Widget _buildCountryPicker(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Center(
child: CountryCodePicker(
initialSelection: 'NL',
),
),
);
}
}
And I open the dialog to select a country. I scroll in the list and then select the TextField my keyboard opens and when I try to type something my entire app freezes. I can't even hot reload. I don't get a single error.
I am running this on my Huawei P30, but I also experience this on other android devices. I don't know if this is a flutter bug or a country code picker bug.
I think it is probably in this widget somewhere. If anyone could point me in the right direction it would help me alot!
class SelectionDialog extends StatefulWidget {
final List<CountryCode> elements;
final bool showCountryOnly;
final InputDecoration searchDecoration;
final TextStyle searchStyle;
final TextStyle textStyle;
final WidgetBuilder emptySearchBuilder;
final bool showFlag;
final double flagWidth;
final Size size;
final bool hideSearch;
/// elements passed as favorite
final List<CountryCode> favoriteElements;
SelectionDialog(
this.elements,
this.favoriteElements, {
Key key,
this.showCountryOnly,
this.emptySearchBuilder,
InputDecoration searchDecoration = const InputDecoration(),
this.searchStyle,
this.textStyle,
this.showFlag,
this.flagWidth = 32,
this.size,
this.hideSearch = false,
}) : assert(searchDecoration != null, 'searchDecoration must not be null!'),
this.searchDecoration =
searchDecoration.copyWith(prefixIcon: Icon(Icons.search)),
super(key: key);
#override
State<StatefulWidget> createState() => _SelectionDialogState();
}
class _SelectionDialogState extends State<SelectionDialog> {
/// this is useful for filtering purpose
List<CountryCode> filteredElements;
#override
Widget build(BuildContext context) => SimpleDialog(
titlePadding: const EdgeInsets.all(0),
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
IconButton(
padding: const EdgeInsets.all(0),
iconSize: 20,
icon: Icon(
Icons.close,
),
onPressed: () => Navigator.pop(context),
),
if (!widget.hideSearch)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextField(
style: widget.searchStyle,
decoration: widget.searchDecoration,
onChanged: _filterElements,
),
),
],
),
children: [
Container(
width: widget.size?.width ?? MediaQuery.of(context).size.width,
height:
widget.size?.height ?? MediaQuery.of(context).size.height * 0.7,
child: ListView(
children: [
widget.favoriteElements.isEmpty
? const DecoratedBox(decoration: BoxDecoration())
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...widget.favoriteElements.map(
(f) => SimpleDialogOption(
child: _buildOption(f),
onPressed: () {
_selectItem(f);
},
),
),
const Divider(),
],
),
if (filteredElements.isEmpty)
_buildEmptySearchWidget(context)
else
...filteredElements.map(
(e) => SimpleDialogOption(
key: Key(e.toLongString()),
child: _buildOption(e),
onPressed: () {
_selectItem(e);
},
),
),
],
),
),
],
);
Widget _buildOption(CountryCode e) {
return Container(
width: 400,
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
if (widget.showFlag)
Flexible(
child: Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Image.asset(
e.flagUri,
package: 'country_code_picker',
width: widget.flagWidth,
),
),
),
Expanded(
flex: 4,
child: Text(
widget.showCountryOnly
? e.toCountryStringOnly()
: e.toLongString(),
overflow: TextOverflow.fade,
style: widget.textStyle,
),
),
],
),
);
}
Widget _buildEmptySearchWidget(BuildContext context) {
if (widget.emptySearchBuilder != null) {
return widget.emptySearchBuilder(context);
}
return Center(
child: Text('No country found'),
);
}
#override
void initState() {
filteredElements = widget.elements;
super.initState();
}
void _filterElements(String s) {
s = s.toUpperCase();
setState(() {
filteredElements = widget.elements
.where((e) =>
e.code.contains(s) ||
e.dialCode.contains(s) ||
e.name.toUpperCase().contains(s))
.toList();
});
}
void _selectItem(CountryCode e) {
Navigator.pop(context, e);
}
}
Also filed an issue on the flutter github https://github.com/flutter/flutter/issues/59886
Edit:
I have a video of it right here
https://www.youtube.com/watch?v=669KitFG9ek&feature=youtu.be
I just had to remove the keys, so there probably was a duplicate key
...filteredElements.map(
(e) => SimpleDialogOption(
//key: Key(e.toLongString()),
child: _buildOption(e),
onPressed: () {
_selectItem(e);
},
),
),
I have a String _value, which I would like to call it from another page.
Here is my players.dart
class MyWidgetPopup extends StatefulWidget {
#override
MyWidgetPopupState createState() => MyWidgetPopupState();
}
enum Answers{FIRST,SECOND}
class MyWidgetPopupState extends State<MyWidgetPopup> {
String _value = '';
void _setValue(String value) => setState(() => _value = value);
Future selectGk(BuildContext context) async {
switch(
await showDialog(
...
...
{
case Answers.FIRST:
_setValue('FIRST TEAM');
break;
case Answers.SECOND:
_setValue('SECOND TEAM');
break;
}
}
So, in players.dart, I can show the selected team with simple code: Text(_value)
But I would like to show it in select.dart
import 'package:flutter/material.dart';
import 'package:myapp/players.dart';
MyWidgetPopupState dataSource = MyWidgetPopupState();
class Besdortbir extends StatefulWidget {
#override
_BesdortbirState createState() => _BesdortbirState();
}
class _BesdortbirState extends State<Besdortbir> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'My Title'),
centerTitle: true,
backgroundColor: Colors.redAccent[700],
elevation: 0.0,
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/field.png"),
fit: BoxFit.fill
)
),
),
//FIRST PLAYER
Container(
padding: EdgeInsets.only(bottom: 90.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
GestureDetector(
onTap: (){dataSource.selectGk(context);}, //I have the FIRST TEAM and SECOND TEAM listed here.
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset('assets/PLUS.png',
scale: 8),
),
),
),
Text(//somehow I would like to show which team is selected by user),
],
),
),
],
),
);
}
}
I have tried to recall setState(), _value, and a few other options. But, I could not be successful.
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