I have a line contains 4 outlinedbuttons and i have 4 widgets ( listview , ListWheelScrollView ,image png and svg image ) i want to display one widget only when i pressed at one outlinedbutton . what should i use for do this in flutter?
provide some code will be helpfull
Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () =>
//show widget1
)),
Expanded(
child: OutlinedButton(
onPressed: () =>
//show widget2
)),
Expanded(
child: OutlinedButton(
onPressed: () =>
//show widget3
)),
Expanded(
child: OutlinedButton(
onPressed: () =>
//show widget4
)),
],
),
)
Create enum
enum WidgetEnum { LISTVIEW, LIST_WHEEL_SCROLLVIEW, IMAGE, SVG_IMAGE }
Global variable for updating the value.
//set the default value.
var isEnumValue = WidgetEnum.LISTVIEW;
Widget
//place this method or place those widget in build method
Widget getVisibleWidget() {
return Container(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
//1
Expanded(
child: OutlinedButton(
onPressed: () {
setEnumValue(WidgetEnum.LISTVIEW);
},
child: Text("Button LISTVIEW"),
),
),
//2
Expanded(
child: OutlinedButton(
onPressed: () {
setEnumValue(WidgetEnum.LIST_WHEEL_SCROLLVIEW);
},
child: Text("Button LIST_WHEEL_SCROLLVIEW"),
),
),
//3
Expanded(
child: OutlinedButton(
onPressed: () {
setEnumValue(WidgetEnum.IMAGE);
},
child: Text("Button IMAGE"),
),
),
//4
Expanded(
child: OutlinedButton(
onPressed: () {
setEnumValue(WidgetEnum.SVG_IMAGE);
},
child: Text("Button SVG_IMAGE"),
),
),
],
),
//1
Visibility(
visible: isEnumValue == WidgetEnum.LISTVIEW,
child: Text("LISTVIEW"),
),
//2
Visibility(
visible: isEnumValue == WidgetEnum.LIST_WHEEL_SCROLLVIEW,
child: Text("LIST_WHEEL_SCROLLVIEW"),
),
//3
Visibility(
visible: isEnumValue == WidgetEnum.IMAGE,
child: Text("IMAGE"),
),
//4
Visibility(
visible: isEnumValue == WidgetEnum.SVG_IMAGE,
child: Text("SVG_IMAGE"),
),
],
),
);
}
Set the enum value for updating Widget visibility.
void setEnumValue(var enumValue){
isEnumValue = enumValue;
setState(() {
});
}
You can do it in different ways.. A simple one would be creating 4 boolean variables for each widget. On pressing button true value for particular widget and false other 3 values. On the otherside, use if(isthiswidget) to display widget if value is true. some demo of code
bool widget1, widget2, widget3, widget4 = false;
onpressing widget1
onPressed: (){
widget1 = true;
widget2, widget3, widget4 = false;}
onpressing widget2
onPressed: (){
setState(() {
widget2 = true;
widget1, widget3, widget4 = false;
});
}
do same for other functions
in UI set condition before every widget
if(widget1)
Container(), //display widget1
if(widget2)
Container() //display widget2
if(widget3)
Container(), //display widget3
if(widget4)
Container() //display widget4
note: use setstate, provider or any other statemanagement method to update realtime values and UI
create this var to identify which widget to show, it will get value from 0 to 3
int widgetNum = 0;
and in onPressed of each button add this, don't forget to add correct num
onPressed: () =>setState(() {
//for example
widgetNum = 2; //for first btn will be = 0 etc..
});
and use visibility to show widget
Column(
children:[
Visibility(
visible: widgetNum==2, // for first widget will be ==0 etc..
child: Container(
// your widget
))]
)
Related
I am using Cards in Flutter and want Progress Indicator at the left bottom position for 2 seconds while Tap on the card so that another page load successfully.
Does anyone know how to add?
Container(
height: 130,
child: Card(
child: Row(
children: <Widget>[
Expanded(
child: ListTile(
title: Text(
'My card Location',
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w700),
),
leading: Icon(Icons.setting),
// color: Colors.blueAccent, size: mediumIconSize),
trailing: Icon(Icons.keyboard_arrow_right),
selected: true,
onTap: () async {
// I try this one but not working
// Flushbar(
//
// showProgressIndicator: true,
// duration: Duration(seconds: 2),
// );
getDetails().then((myCardlocations) {
Navigator
.of(context)
.pushNamed('/myCardlocations',
arguments: ObjectLocations(locations, 'myCardlocations'));
}
);
}
),
),
],
),
),
),
You can do something like this using Stack and CircularProgressIndicator..
class _MyWidgetState extends State<MyWidget> {
bool isLoading = false;
#override
Widget build(BuildContext context) {
return Container(
height: 130,
child: Stack(
children: [
Container(
height: 130,
child: Card(
child: Row(
children: <Widget>[
Expanded(
child: ListTile(
title: Text(
'My card Location',
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w700),
),
leading: Icon(Icons.settings),
// color: Colors.blueAccent, size: mediumIconSize),
trailing: Icon(Icons.keyboard_arrow_right),
selected: true,
onTap: () async {
setState(() {
isLoading = true;
});
getDetails().then((myCardLocations) {
setState(() {
isLoading = false;
});
// navigation code here
});
},
),
),
],
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: isLoading
? Padding(
padding: EdgeInsets.fromLTRB(15,0,0,15),
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(),
),
)
: SizedBox(),
),
],
),
);
}
}
Edit:
Looks like I misunderstood the question a bit. Specifically, the place where to show the progress indicator. Anyways, if you get the idea, you can put the indicator at a different place as per your requirement.
There are certain things, which I would like to mention before I give the actual answer.
Read about Flutter.delayed constructor, very useful thing to make some thing wait for a while and do the operation by providing Duration. Whatever you want to do after that duration, it will implement in the callback function
Future.delayed(Duration(seconds: your_time, (){
//it will perform this operation after that much of seconds
}));
You can always show/hide a Widget using bool value, and make changes accordingly
Use a column and Add the LinearProgressIndicator at the end of the Widget. Show/hide it based up on the data
Also, use MediaQuery to give out the height. It is more efficient way of giving the dimensions according to all phone size. Like match-parent in Android Studio. Do the math accordingly, I have shown in the code also
Column(
children: [
Row(),
bool val ? LinearProgressIndicator() : Container() // Container() is nothing but an empty widget which shows nothing
]
)
Some heads up: I have not used getData, since it is not defined properly but you can call it the in function which I will show you in the code, that is pageTransit(). Follow the comments and you are good to go
class _MyHomePageState extends State<MyHomePage> {
// this takes care of the show/hide of your progress indicator
bool _showProgress = false;
// this takes care of the operation
void pageTransit(){
// first show when the ListTile is clicked
setState(() => _showProgress = true);
Future.delayed(Duration(seconds: 2), (){
// hide it after 2 seconds
setState(() => _showProgress = false);
// do the page trnasition here
//getDetails().then((myCardlocations) {
//Navigator.of(context).pushNamed('/myCardlocations',
//arguments: ObjectLocations(locations, 'myCardlocations'));
//}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
height: MediaQuery.of(context).size.height * 0.1,
child: Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// use your items here, based upon the bool value show hide your
// progress indicator
Row(
children: <Widget>[
Expanded(
child: ListTile(
title: Text(
'My card Location',
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w700),
),
leading: Icon(Icons.settings),
// color: Colors.blueAccent, size: mediumIconSize),
trailing: Icon(Icons.keyboard_arrow_right),
selected: true,
onTap: () => pageTransit()
)
)
]
),
// show/hide in the card
_showProgress ? LinearProgressIndicator() : Container()
]
)
)
)
);
}
}
Result
Look at the ProgressIndicator, it remains there for 2 seconds, and then goes away
1. You need to define a GlobalKey for the Scaffold so that you can use a SnackBar (you can define the GloablKey in your page's State).
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
2. You need to set the key for the Scaffold.
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
...
3. You need to wrap the Card with a GestureDetector and set the onTap function to call showLoading which shows a SnackBar on the bottom of the screen. Call your getDetails function in the showLoading. Full code (except the define key step):
void _showLoading() {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
duration: new Duration(seconds: 2),
content: new Row(
children: <Widget>[
new CircularProgressIndicator(),
new Text("Loading...")
],
),
));
// call to your getDetails and its steps should be here
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("My app"),
),
body: Center(
child: GestureDetector(
child: Card(
child: Row(children: <Widget>[
Expanded(
child: ListTile(
title: Text(
'My card Location',
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700),
),
leading: Icon(Icons.settings),
// color: Colors.blueAccent, size: mediumIconSize),
trailing: Icon(Icons.keyboard_arrow_right),
selected: true,
)),
])),
onTap: () => _showLoading(),
)),
);
}
}
Note: you can also style the SnackBar.
Result:
I'm looking for the button to be enabled or disabled, while I'm writing in the textField. If the length of the text is greater than 0, I need the button to be enabled.
final myController = TextEditingController();
static var nameProduct;
#override
void initState() {
super.initState();
}
return Dialog(
shape: RoundedRectangleBorder(),
child: Container(
child: Stack(
children: <Widget>[
Container(child: Center(
child: Column(
children: <Widget>[
TextField(
autofocus: true,
controller: myController,
onChanged: (String text) {
nameProduct = text;
},
),
Padding(
child: Row(
children: <Widget>[
Container(
child: RaisedButton(
onPressed: (nameProduct.isNotEmpty)
? () => {
Navigator.of(context)
.pop(false),
myMethod()
}
: null,
),
),
],
),
),
],
),
),
)
],
),
));
With the code I publish here, it's not working for me.Thanks
The build method is not being called again to perform the redraw.
You can use the setState(() {}); like this:
onChanged: (String text) {
setState(() {
nameProduct = text;
});
},
Problem here is that the widget is only built once. Therefore, subsequent changes to your textfield do not tell Flutter to rebuild the widget.
I've tried a lot, but I can't change the height of AlertDialog when I use Slider. I saw here on the Forum the suggestion to use ConstrainedBox. Did n't work. Is there a better way to show the Slider?
#override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints(maxHeight: 100.0),
child: AlertDialog(
title: Text('Selecione a velocidade'),
content: Container(
child: Slider(
value: _fontSize,
label: _fontSize.round().toString(),
min: 20,
max: 200,
divisions: 18,
onChanged: (value) {
setState(() {
_fontSize = value;
});
},
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
print('cancelar');
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('Cancelar'),
),
FlatButton(
onPressed: () {
print('salvar');
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('Salvar'),
),
FlatButton(
onPressed: () {
print('aplicar');
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('Aplicar'),
),
],
),
);
}
I attached an image showing how AlertDialog looks.
You need to define the height for the Container which outside the Slider.
content: Container(
height:50, // define any height you want here
child: Slider(
This is how the output looked like.
Try this.
Dart pad to show your output
Let me know if it work out for you or not.
Code is here
#override
Widget build(BuildContext context) {
return FittedBox(
child: AlertDialog(
title: Text('Selecione a velocidade'),
content: Container(
child: Slider(
value: _fontSize,
label: _fontSize.round().toString(),
min: 20,
max: 200,
divisions: 18,
onChanged: (value) {
setState(() {
_fontSize = value;
});
},
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
print('cancelar');
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('Cancelar'),
),
FlatButton(
onPressed: () {
print('salvar');
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('Salvar'),
),
FlatButton(
onPressed: () {
print('aplicar');
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('Aplicar'),
),
],
),
);
}
}
I'am trying to create a custom widget CarteSim and I'am trying to call it everytime I click on Floating Action Button , but unfortunately it doesn't show when I call it inside the button , but it shows when I call it in the Scaffold , please who has ever experience that
here s my code
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.pink,
title: Text(" INWI "),
),
body: SingleChildScrollView(
child: Container(
child: Center(
child: Column(
children: <Widget>[
DropdownButton<String>(
items: _type.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),
onChanged: (String newValueSelected) {
setState(() {
this._currentItemSelected = newValueSelected;
});
},
value: _currentItemSelected,
),
Divider(
color: Colors.black,
),
new Row(
children: [
new Text(" type client supporte * carte avec 1 cin"),
new Checkbox(value: _isChecked, onChanged: (bool value){ onChanged(value);}),
]
),
Divider(
color: Colors.black,
),
new Column(
children: <Widget>[
CarteCin(),
CarteSim(),
]
)
],
),
),
)
),
floatingActionButton: FloatingActionButton(
onPressed: (){
Column(
children: <Widget>[
CarteSim(),
]
);
},
child: Icon(Icons.add),
backgroundColor: Colors.pink,
),
);
}
]
}
you are misunderstanding the process. The onPressed key actually used for call actions on press the floatingActionButton. You can write functions there, like you can update your state or print anything on your console or call an API to get data. But you can't display any widget from there.
Now what you're trying to do, that can be resolved like this. Whenever you press that button you should update your state, i.e bool show. Then modify your Column children based on that show state.
Here is an example how tu update the UI in flutter
class FrontPage extends StatefulWidget {
#override
_FrontPageState createState() => _FrontPageState();
}
class _FrontPageState extends State<FrontPage> {
bool currentStateShowsThis;
initState() {
currentStateShowsThis = false;
super.initState();
}
Widget build(BuildContext context) {
final color = currentStateShowsThis ? Colors.blue : Colors.red;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.pink,
title: Text(" INWI "),
),
body: SingleChildScrollView(
child: Container(
child: Center(
child: Column(
children: <Widget>[
Container(width: 100, height: 100, color: color,) // alternatively you can change the widgets being displayed
],
),
),
)
),
floatingActionButton: FloatingActionButton(
onPressed: (){
setState(() {
currentStateShowsThis = !currentStateShowsThis;
});
},
child: Icon(Icons.add),
backgroundColor: Colors.pink,
),
);
}
}
In your example "the button" will call back the
onPressed:
Which will only create the widgets in that method (Column ...) and not place them in a the layout.
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