Fill ListView tiles vertically by a container - Flutter - 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

Related

I made customize horizontal stepper in flutter and it's not scrolled till the end

Does anyone know how to make my stepper scrollable in vertically, it actually could scroll but it doesn't scrolling till the end of the page length
The stepper:
MainScaffold(
title: appBarTitle,
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
width: width,
child: Column(
children: <Widget>[
const SizedBox(
height: 8,
),
Row(
children: _lineViews(),
),
const SizedBox(
height: 8,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: _titleViews(),
),
const SizedBox(
height: 20,
),
Expanded(
child: ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: stepPanels())
],
),
),
const SizedBox(
height: 20,
),
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: _buttonControls(currentStep, context),
);
I put the stepper's content inside expanded listview, and I already add shrinkwrap & physics into it, when I call this customizable widget on another class, it can't be scrolled till the end of the page
Steps(
content: Obx(
() {
if (controller.loading.value) {
return const LoadingProgressIndicator();
} else {
return SizedBox(
height: MediaQuery.of(context).size.height,
child: ListView(
physics: const ClampingScrollPhysics(),
children: [
controller.loading.value
? const LoadingProgressIndicator()
: _doctorProfile(),
const SizedBox(height: 10.0),
const ClinicTypeToggle(),
const SizedBox(height: 100.0),
],
),
);
}
},
),
),
that is the content that I want to scroll

Bottom overflow 13 pixels

How can fix it?
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
fit: StackFit.loose,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
flex: 2,
child: buildSearch(),
),
Expanded(
flex: 2,
child: Container(color: Colors.green),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Frequitly Visited'),
TextButton(
onPressed: () {},
child: Text('Show More'),
),
],
),
Expanded(
flex: 6,
child: buildSites(size),
)
],
)
],
),
);
}
buildSearch() {
return Container(
child: FloatingSearchBar(
transitionCurve: Curves.easeInOutCubic,
transition: CircularFloatingSearchBarTransition(),
physics: const BouncingScrollPhysics(),
scrollPadding: EdgeInsets.zero,
builder: (context, _) => _history(),
),
);
}
Container buildSites(size) {
return Container(
color: Colors.black,
width: size.width,
);
}
Widget _history() {
List<String> listHistory = [
'Flutter',
'Python',
'Nodejs',
'Rails',
];
return ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Material(
child: Column(
children: listHistory
.map((e) => ListTile(
title: Text(e),
onTap: () {},
))
.toList(),
),
),
);
}
}
try to fixed the height of search & container, expanded only flexible part:
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 100,
child: buildSearch(),
),
Container(
height: 100,
child: Container(color: Colors.green),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Frequitly Visited'),
TextButton(
onPressed: () {},
child: Text('Show More'),
),
],
),
Expanded(
child: buildSites(size),
)
],
)
You can just remove the Expanded widget wrapped around your buildSearch() widget and give a desired padding or you can also your sizedbox with a desiredHeight below and above the buildSearch()
so basically change
...
Expanded(
flex: 2,
child: buildSearch(),
),
...
to
...
Padding(
padding:EdgeInsets.only(top:20,bottom:50), // adding a suitable padding should fix it
child:buildSearch(),
)
...

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

Refresh ListView.builder On Button Click in 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.

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(),
],
),