Refresh ListView.builder On Button Click in Flutter - flutter

I am using the below code, where I have a ListView that had a switch.
I want to implement something like when I click on the RaisedButton - it will reload the ListView and all the values of switch.value should be changed to either true or false.
The user can either change the value of the switch from items in the ListView or from the button click.
I do not have an idea on how I should change the value or all the switches in the ListView.
return Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 2,
height: 100,
padding: EdgeInsets.all(20),
child: RaisedButton(
onPressed: () {
},
child: Text(
BTN_START_TRIP,
style: new TextStyle(
fontSize: 20.0,
),
),
textColor: buttonFontColor,
color: buttonColor,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(15.0))
),
),
Expanded(
child: ListView.builder(
padding: EdgeInsets.all(3.0),
// Let the ListView know how many items it needs to build.
itemCount: snapshot.data.results.length,
// Provide a builder function. This is where the magic happens.
// Convert each item into a widget based on the type of item it is.
itemBuilder: (context, index){
return Container(
height: 120,
child: Card(
elevation: 10,
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print(snapshot.data.results[index].original_title);
},
child: Container(
height: 120,
child: Row(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(20, 0, 5, 0),
width: MediaQuery.of(context).size.width -90,
child: Align(
alignment: Alignment.topLeft,
child: Text(snapshot.data.results[index].original_title,
textAlign: TextAlign.left,
style: TextStyle(fontSize: defaultTitleFontsize, color: defaultFontColor),
maxLines: 5),
),
),
Container(
padding: EdgeInsets.fromLTRB(20, 0, 5, 0),
child: Align(
alignment: Alignment.topLeft,
child: Text(snapshot.data.results[index].original_language,textAlign: TextAlign.left,style: TextStyle(fontSize: defaultsubTitleFontsize, color: defaultFontColor)),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
child: Switch(
value: false,
onChanged: (value){
setState(() {
print(value);
});
}
),
),
],
),
]
),
),
),
),
);
},
),
)
],
);

You'll need to have a variable to decide if the switch should be on or off. And during a certain event (click of button e.g) set the variable to appropriate value & re-trigger the build (re-painting of the UI) by calling setState. You'll need to have the above logic part of a stateful widget to accomplish that.

Related

Not click on Container in Stack

I have a problem with the Stack Widget.
I have a Stack that contains two children: an Image wrapped with GestureDetector and a Container
. When i click anywhere on the Container, whoever is last on the Stack children list his onTap
I am extremely new to flutter.
Screenshot of the screen
this code
sonItem(dynamic icon ,String text,Color color){
return GestureDetector(
onTap: () {
print("dddddddddddddddd");
},
child: Container(
width: 70,
height: 100,
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
child: Column(
children: [
Icon(icon ,color: color,),
Text(text)
],
),
),
);
}
I Have a problem with the Stack Widget.
I have a Stack that contains two children: an Image wrapped with GestureDetector and an Container
. When i click anywhere on the Container , whoever is last on the Stack children list his onTap
body: Container(
color: Colors.white,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Color(0xffF0F0F0),
height: 200,
child: Stack(
overflow: Overflow.visible,
alignment: Alignment.center,
children: [
Positioned(
bottom: -170.0,
child: Container(
padding: EdgeInsets.only(top: 40 , right: 10, left: 10),
height: 250,
decoration: BoxDecoration(
color: Color(0xffFFFFFF),
borderRadius: BorderRadius.circular(30),
border: Border.all(
width: 1,
color: Colors.black,
style: BorderStyle.solid,
),
),
child: Column(
children: [
Text('company',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Colors.black,
),
),
Text("The number 2000"),
RatingBar(
rating: 3,
icon:Icon(Icons.star,size:20,color: Colors.grey,),
starCount: 5,
spacing: 5.0,
size: 20,
isIndicator: false,
allowHalfRating: true,
onRatingCallback: (double value,ValueNotifier<bool> isIndicator){
print('Number of stars--> $value');
//change the isIndicator from false to true ,the RatingBar cannot support touch event;
isIndicator.value=true;
},
color: Colors.amber,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
sonItem(Icons.phone,"call us",Colors.green),
sonItem(Icons.location_on_outlined,"location",Colors.red),
sonItem(Icons.facebook,"FaceBook",Colors.blue),
sonItem(Icons.add_ic_call_outlined,"whatsapp",Colors.green)
],
)
],),
)),
Try below code hope its help to you
Stack(
children: <Widget>[
//your InkWell or GestureDetector Widget
InkWell(
child: Container(
// your child Widget
),
onTap: () {},
),
Positioned(),
]
),
The problem is solved when I delete bottom: -170.0,
But I need it in the design

Flutter error:Failed assertion: line 1785 pos 12: 'hasSize'

I have a code of recording Audio in flutter. The code should work perfectly without errors, whenever I try to call it from an alert dialog I end up with an error
The following assertion was thrown during performLayout():
RenderShrinkWrappingViewport does not support returning intrinsic
dimensions.
Calculating the intrinsic dimensions would require instantiating every
child of the viewport, which defeats the point of viewports being
lazy.
If you are merely trying to shrink-wrap the viewport in the main axis
direction, you should be able to achieve that effect by just giving
the viewport loose constraints, without needing to measure its
intrinsic dimensions.
Am trying to pass an option to record audio to an alert dialog. Users to record audio from a pop up instead of a main screen. What am I doing wrong?
What i have so far
Widget setupAlertDialoadContainer() {
return ListView(
shrinkWrap: true, //just set this property
padding: const EdgeInsets.all(8.0),
//children: listItems.toList(),
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 24.0, bottom: 16.0),
child: Text(
this._recorderTxt,
style: TextStyle(
fontSize: 48.0,
color: Colors.black,
),
),
),
_isRecording
? LinearProgressIndicator(
value: 100.0 / 160.0 * (this._dbLevel ?? 1) / 100,
valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
backgroundColor: Colors.red,
)
: Container()
],
),
Row(
children: <Widget>[
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(10.0),
child: FloatingActionButton(
heroTag: "Record",
onPressed: () {
if (!this._isRecording) {
return this.startRecorder();
}
this.stopRecorder();
},
child: this._isRecording ? Icon(Icons.stop) : Icon(Icons.mic),
),
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 60.0, bottom: 16.0),
child: Text(
this._playerTxt,
style: TextStyle(
fontSize: 48.0,
color: Colors.black,
),
),
),
],
),
Row(
children: <Widget>[
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(8.0),
child: FloatingActionButton(
heroTag: "Start",
onPressed: () {
startPlayer();
},
child: Icon(Icons.play_arrow),
),
),
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(8.0),
child: FloatingActionButton(
heroTag: "Pause",
onPressed: () {
pausePlayer();
},
child: Icon(Icons.pause),
),
),
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(8.0),
child: FloatingActionButton(
heroTag: "Stop",
onPressed: () {
stopPlayer();
},
child: Icon(Icons.stop),
),
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
Container(
height: 56.0,
child: Slider(
value: slider_current_position,
min: 0.0,
max: max_duration,
onChanged: (double value) async {
await flutterSound.seekToPlayer(value.toInt());
},
divisions: max_duration.toInt()))
],
);
}
How am passing the data to the Alert dialog
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Record the data collection'),
content: setupAlertDialoadContainer(),
);
});
is the error is showing when alert box is opened??
if yes my suggestion is using
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Record the data collection'),
content: Container(
child:setupAlertDialoadContainer(),
height:200,
width:200,
),
);
});
change the width and height of container according to your need

Fill ListView tiles vertically by a container - Flutter

I have been trying to put a line indicator on the left most margin of the card in my flutter app. I've tried a lot of things but didn't work.
There's an exact question here, which is actually the same issue I've been trying to solve.
The problem with the accepted solution is that it restricts the height of the hardcoded value, which I don't want. Rather the color should automatically fill the height of the card.
The Problem
I've tried all the three solutions and none of them fit my use case.
Output from first solution
Here I've to hardcode the value to something larger so that all the text being displayed lies well inside it. That's something I feel is not a solution.
Card(
key: ObjectKey(noteList[index]),
elevation: 2.0,
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 4,
color: Color(noteList[index].intcolor),
),
Flexible(
flex: 100,
child: ListTile(
~~~~~~~~~~~~~~~~~ SNIP ~~~~~~~~~~~~~~~~~~~~~~~~
chip goes outside
Output from Second solution
This doesn't show anything at all.
Card(
key: ObjectKey(noteList[index]),
elevation: 2.0,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
constraints: BoxConstraints.expand(),
color: Color(noteList[index].intcolor),
),
),
Flexible(
flex: 100,
child: ListTile(
~~~~~~~~~~~~~~~~~ SNIP ~~~~~~~~~~~~~~~~~~~~~~~~
No output at all
Output from last solution
There's no color from the container.
There's no color from the container
Thanks a lot.
Update 1 ( Monday, 6 April 2020 8:16 pm GMT )
Added code and repo for easy replication.
Repo
main.dart
import 'package:flutter/material.dart';
void main() {
List<String> notes = [
"fluttermaster.com",
"Update Android Studio to 3.3",
"Something long Something long Something long Something long Something long Something long",
];
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Simple Note ListView"),
),
body: Container(
color: Colors.white10,
padding: EdgeInsets.all(16.0),
child: HomePage(notes)),
),
));
}
class HomePage extends StatelessWidget {
final List<String> notes;
HomePage(this.notes);
Widget build(BuildContext context) {
return ListView.builder(
itemCount: notes.length,
itemBuilder: (context, pos) {
return Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: Card(
elevation: 2.0,
child: Row(
// key: _cardKey,
children: <Widget>[
Flexible(
flex: 1,
child: Container(
// -------------------- This here ----------------------------------------------
// FixMe : This shouldn't be hardcoded, rather it should fill the height of it's parent element, in this case card
// https://medium.com/#diegoveloper/flutter-widget-size-and-position-b0a9ffed9407
height: 71,
color: Colors.green,
// -------------------- This here ----------------------------------------------
),
),
Flexible(
flex: 100,
child: ListTile(
// For center alignment from vertical and horizontal : https://stackoverflow.com/a/51546279
// Since using CircleAvatar does this but it decreases size of icon too : https://github.com/flutter/flutter/issues/16061
leading: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.receipt),
],
),
title: Text(
notes[pos],
),
subtitle: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(notes[pos].substring(0, 10)),
// What is the best way to optionally include a widget in a list of children
// https://github.com/flutter/flutter/issues/3783#issuecomment-506019822
if ((pos % 2) == 0)
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Icon(Icons.timer),
),
label: Text('2FA'),
),
],
),
trailing: Padding(
padding: EdgeInsets.all(10),
child: Wrap(
spacing: 10,
direction: Axis.vertical,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(
Icons.check,
color: Colors.grey,
),
onPressed: () {},
)
]),
),
onTap: () {},
),
),
],
),
));
},
);
}
}
Perhaps one way of doing it is to use Stack
ListView.builder(
itemCount: notes.length,
itemBuilder: (context, pos) {
return Padding(
padding: EdgeInsets.all(8),
child: Stack(
children: <Widget>[
Card(
margin: EdgeInsets.zero,
child: ListTile(
leading: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.receipt),
],
),
title: Text(
notes[pos],
),
subtitle: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(notes[pos].substring(0, 10)),
if ((pos % 2) == 0)
Chip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Icon(Icons.timer),
),
label: Text('2FA'),
),
],
),
trailing: Padding(
padding: EdgeInsets.all(10),
child: Wrap(
spacing: 10,
direction: Axis.vertical,
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(
Icons.check,
color: Colors.grey,
),
onPressed: () {},
)
]),
),
onTap: () {},
),
),
Positioned(
top: 0,
bottom: 0,
child: Container(
width: 5,
color: Colors.green,
),
)
],
),
);
},
)
Output

What is best way to remove overflowing by a lot of pixels in Flutter?

I have Stepper in my app, and I have problems with placing textfield on screen, when I want to text some text in textfield, appears keyboard and over it shows me that:
A RenderFlex overflowed by 139 pixels on the bottom.
I read some articles and understood, that I have to use FittedBox, but I dunno how to use it with best way. How can I reach my goal?
Code:
#override
Widget build(BuildContext context) {
globalHeight = (MediaQuery.of(context).size.height) * 0.85;
return Scaffold(
body: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: Container(
decoration: BoxDecoration(color: colorsBackround[_currentPage]),
child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
height: globalHeight,
child: PageView(
physics: ClampingScrollPhysics(),
controller: _pageController,
onPageChanged: (int page) {
setState(() {
_currentPage = page;
});
},
children: <Widget>[
// some code
Padding(
padding: EdgeInsets.all(10.0),
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Image(
image: AssetImage(
itemIcon[_currentPage],
),
height: 300.0,
width: 300.0,
),
Text(
'Укажите ваш возраст',
style: kTitleStyle,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.8,
height: 50.0,
child: Padding(
padding: EdgeInsets.only(
top: 20.0,
left: 20,
right: 20,
bottom: MediaQuery.of(context)
.viewInsets
.bottom),
child: TextField(
controller: ageController,
keyboardType: TextInputType.number,
onChanged: (text) {
setState(() {
if (text.isNotEmpty) {
inputs[1] = true;
} else {
inputs[1] = false;
}
});
},
decoration: InputDecoration(
labelText: 'Возраст',
),
style: TextStyle(fontSize: 18.5),
)),
),
],
),
),
),
//some code
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: _buildPageIndicator(),
),
_currentPage != _numPages - 1
? Expanded(
child: Container(
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: Align(
alignment: FractionalOffset.bottomLeft,
child: FlatButton(
onPressed: () {
_pageController.previousPage(
duration: Duration(milliseconds: 500),
curve: Curves.ease,
);
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.arrow_back,
color: Colors.white,
size: 26.0,
),
SizedBox(width: 10.0),
Text(
'Назад',
style: TextStyle(
fontFamily: 'Century Gothic',
color: Colors.white,
fontSize: 14.5,
),
),
],
),
),
)),
Expanded(
child: Align(
alignment: FractionalOffset.bottomRight,
child: FlatButton(
onPressed: () {
_pageController.nextPage(
duration: Duration(milliseconds: 500),
curve: Curves.ease,
);
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Дальше',
style: TextStyle(
fontFamily: 'Century Gothic',
color: Colors.white,
fontSize: 14.5,
),
),
SizedBox(width: 10.0),
Icon(
Icons.arrow_forward,
color: Colors.white,
size: 26.0,
),
],
),
),
)),
],
)))
: Text(''),
],
),
),
),
),
bottomSheet: _currentPage == _numPages - 1
? Container(
height: 75.0,
width: double.infinity,
color: Theme.of(context).scaffoldBackgroundColor,
child: GestureDetector(
onTap: () => print('Get started'),
child: Center(
child: Padding(
padding: EdgeInsets.only(bottom: 15.0),
child: Text(
'Начать',
style: TextStyle(
fontFamily: 'Century Gothic',
color: Colors.white,
fontSize: 21.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
)
: Text(''),
);
}
}
There is no direct solution to prevent overflowing issues, it depends on your current code. So, here you use
Add to your Scaffold
resizeToAvoidBottomInset: false
Wrap your widget in SingleChildScrollView
SingleChildScrollView(
child: YourColumn(),
)
That happens because when opening the keyboard, the body is resized to avoid the keyboard appear over the text field, and since your content isn't scrollable the content of the body gets overflowed. Check this property of the Scaffold:
/// If true the [body] and the scaffold's floating widgets should size
/// themselves to avoid the onscreen keyboard whose height is defined by the
/// ambient [MediaQuery]'s [MediaQueryData.viewInsets] `bottom` property.
///
/// For example, if there is an onscreen keyboard displayed above the
/// scaffold, the body can be resized to avoid overlapping the keyboard, which
/// prevents widgets inside the body from being obscured by the keyboard.
///
/// Defaults to true.
final bool resizeToAvoidBottomInset;
If you put that to false, the body won't be resized so the content won't be overflowed.
If you leave it as default, you need to make the body scrollable. In your case, you could change the root Column for a ListView and you will need to remove the Expanded wrap of the third item of the column.
But I recommend you to try to simplify the structure of the widgets.
Wrap your widget with a SingleChildScroll widget and that should work and solve the overflow issue

How to put scroll view inside stack widget in flutter

I am making a flutter application in which i uses body as a stack and in this stack i have two child.One is main body and other is back button which is at top of screen.The first child of stack is scrollview.Here is my build method.
Widget build(BuildContext context) {
return Scaffold(
//debugShowCheckedModeBanner: false,
key: scaffoldKey,
backgroundColor: Color(0xFF5E68A6),
body: Stack(
children: <Widget>[
Container(
margin: const EdgeInsets.fromLTRB(0.0, 10.0 , 0.0 , 0.0 ),
height: double.infinity,
child:CustomScrollView(
slivers: <Widget>[
new Container(
margin: EdgeInsets.all(15.0),
child:Text(getTitle(),
style: TextStyle(fontSize: 20.0,fontWeight: FontWeight.bold,color: Colors.white),
),
),
//middle section
_isLoading == false ?
new Expanded(child: GridView.builder(
itemCount: sub_categories_list.length,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (context, position){
return InkWell(
child: new Container(
//color: Colors.white,
padding: EdgeInsets.all(20),
margin: EdgeInsets.all(10),
height: 130,
width: 130,
child: new Center(
child :
Text(sub_categories_list[position].name,
style: TextStyle(fontSize: 18.0,fontWeight: FontWeight.bold),
)
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16)),
// border: Border.all(color: Colors.black, width: 3),
),
),
onTap: () {
//write here
// Fluttertoast.showToast(msg: "You clicked id :"+sub_categories_list[position].cat_id.toString());
Navigator.pushNamed(context, '/advicemyself');
},
);
}
))
:
CircularProgressIndicator(),
Container(
margin: EdgeInsets.all(18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Column(
children: <Widget>[
Image.asset('assets/bt1.png'),
Container(
margin: EdgeInsets.all(10.0),
child: Text("FIND HELP",
style: TextStyle(fontSize: 18.0,color: Colors.white),
),
)
],
),
new Column(
children: <Widget>[
Image.asset('assets/bt2.png'),
Container(
margin: EdgeInsets.all(10.0),
child: Text("HOME",
style: TextStyle(fontSize: 18.0,color: Colors.white),
),
)
],
),
new Column(
mainAxisAlignment:MainAxisAlignment.spaceEvenly,
children: <Widget>[
Image.asset('assets/bt3.png'),
Container(
margin: EdgeInsets.all(10.0),
child: Text("CALL 999",
style: TextStyle(fontSize: 18.0,color: Colors.white),
),
)
],
),
],
),
),
],
),
),
Positioned(
left: 10,
top: 30,
child: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => {
//go back
},
color: Colors.white,
iconSize: 30,
),
),
// makeview()
],
),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
I have also tried using SingleChildScrollView but that also does not works.What i am doing wrong here ?
Here is link to the design which i want to make.
https://imgur.com/a/w7nLmKC
The back should be above scroll view so i used stack widget.
Running your sample code, there doesn't seem to be a need for overlapping widgets. Using Stack seems to be unnecessary. One way you could do is by using Column widget, and using Expanded as you see fit.
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Widget(), // back button goes here
CustomScrollView(...),
],
),
);
}
Otherwise, if you really need to use Stack, the scroll function should work fine. I've tried this locally and the Stack widget doesn't interfere with scrolling of Slivers, ListView, and GridView.
Stack(
children: [
/// Can be GridView, Slivers
ListView.builder(),
/// Back button
Container(),
],
),