move singlechildscroll view back to top position after refresh in flutter - flutter

whenever I tap on any of the options of the given 4 buttons, my new data loads in the text and in the 4 option fields.
but the scroll view doesn't come back to its normal position, instead, it remains down, at what position I had left it, previously.
so how to get singlechildscrollview back to its original form after every refresh?
Expanded(
child: Container(
width: MediaQuery.of(context).size.width,
margin:EdgeInsets.only(top: 50.0,bottom: 50) ,
decoration: BoxDecoration(
color: Color(0xFFf2f2f2),
borderRadius: BorderRadius.only(topRight: Radius.circular(40),topLeft:Radius.circular(40) ),
),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
height: 800,
child: (
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 50,left: 20,right: 20),
child: Text(question.replaceAll("\\n", "\n"),style: TextStyle(fontWeight: FontWeight.bold,fontSize: 18),),
),
SizedBox(height: 20),
optionButton(text: option1),
SizedBox(height: 30),
optionButton(text: option2),
SizedBox(height: 30),
optionButton(text: option1),
SizedBox(height: 30),
optionButton(text: option2),
SizedBox(height: 30),
Spacer(),
Column(
children: [
Text("TOTAL"),
Container(
width: MediaQuery. of(context). size. width,
color: Colors.blue,
child:
Center(child: Text(score.toString(),)),),
SizedBox(height: 20)
],),
],
)
),
),
),
),
),

Since I'm not sure what optionButton looks like, you'll probably need this first above your build method:
ScrollController scrollController = new ScrollController();
Then if your optionButton is within the same class, call this within your button function onTap(){} or onPressed(){} :
scrollController.jumpTo(0.0);
Make sure to add the controller to SingleChildScrollView
If optionButton is from a different class, then I'll have to change my answer.
Let me know if this helps!

Related

Add Text widget to ListView that has its children mapped in Flutter?

I have a ListView that presents its children from a map dynamically. The ListView is inside an animated controller that shows and hides the ListView. How would I add one Text widget to the bottom of the ListView? Or should I use ListView.builder instead?
AnimatedContainer(
duration: Duration(milliseconds: duration),
height: _expandRedFlag ? (args.map1.length * 37.0 + 20) : 0,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Container(
child: ListView(
physics: NeverScrollableScrollPhysics(),
children: args.map1.entries
.map((e) => Column(children: [
Row(
textDirection: TextDirection.rtl,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Text(
"${e.value}",
style: TextStyle(fontSize: 14),
),
SizedBox(
width: 8,
height: 25,
),
Expanded(
child: Text(
e.key,
style: TextStyle(fontSize: 14),
),
),
],
),
Container(
height: 2,
width: double.infinity,
child: Divider(
color: Colors.black,
),
),
]))
.toList(),
),
),
),
Flutter has a ready to use solution for this!
Use AnimatedList
A scrolling container that animates items when they are inserted or removed. This widget's AnimatedListState can be used to dynamically insert or remove items. To refer to the AnimatedListState either provide a GlobalKey or use the static of method from an item's input callback. This widget is similar to one created by ListView.builder.

Vertically center content inside SingleChildScrollView with min height of screen height

I am trying to create a web layout that that consists of a scrollable column that has a min height of the screen height but can expand past the screen height if the content is too large. I have been able to create the scrolling container but I cannot vertically center the main content while still making the entire sections scrollable. The only working version I can get wont vertically center the content, I have to added a SizedBox above it to create padding to make it look centered but then its not responsive on different heights.
The parent of the content looks like this:
Container(
width: MediaQuery.of(context).size.width / 2,
height: double.infinity,
padding: const EdgeInsets.fromLTRB(100, 30, 100, 0),
child: SingleChildScrollView(
child: Column(
children: [
LoginLayout(),
SizedBox(height: 30),
],
),
),
),
Then to simplify the content column, its basically this:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
child: Image.asset(
'assets/images/2.0x/logo-full.png',
width: 125,
fit: BoxFit.contain,
),
),
// This column needs to be vertically centered if fits in the screen height
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text('Welcome Back!', style: _textTheme.headline2),
SizedBox(height: 10),
Text('Sign in to continue', style: _textTheme.bodyText2),
SizedBox(height: 60),
EmailInput(label: 'EMAIL'),
SizedBox(height: 30),
PasswordInput(label: 'PASSWORD'),
SizedBox(height: 60),
Button(
label: 'Login',
icon: Icons.link,
theme: ButtonColor.PRIMARY,
onPressed: () {},
),
],
),
],
);
I was able to apply an Expanded widget around the centered column which did work but then I lost the ability to scroll if the content was larger that the screen height.
Here is an example for reference as well
Not sure how to do that in SingleChildScrollView though,
try using ListView with shrinkWrap: true
Container(
width: MediaQuery.of(context).size.width / 2,
height: double.infinity,
padding: const EdgeInsets.fromLTRB(100, 30, 100, 0),
child: Center(
child: ListView(
shrinkWrap: true,
children: [
LoginLayout(),
],
)
),
)

overflowing flutter columns and rows

I have this list view in flutter which I am trying to make into a chat list. Similar to what you see in WhatsApp and telegram. However I am struggling to get the idea of how rows and columns work because I keep getting overflows.
Here is the code:
ListView(
physics: BouncingScrollPhysics(),
children: [
Dismissible(
key: Key(""),
background: Container(color: Colors.grey[200]),
direction: DismissDirection.endToStart,
child: InkWell(
onTap: () {},
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flex(
direction: Axis.vertical,
children: [
Text("Hello"),
],
),
Flex(
direction: Axis.vertical,
children: [
Text(
"al;skdl;aksd a;skd ;aks;dk a;skd ;laks;d a;lsk d;lkas; dka;lsk d;laks; ldka;slk d;a",
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
],
),
],
),
),
),
],
Now we often experience the text overflow problem so if we think it that we we have provided column a particular width and restricted it but if we wrap the things up with flexible widget it now tells column/Row that you can change your size and be flexible
order would be
flexible > Container > Column/Row
The reason we are applying this to container is Column/Row will ask immediate parent for width and height
now this problem can also be solved by text overflow property that is we can clip text but what if we dont want too
So all you have to do is Wrap the column/Row in Container and then into Flexible as now it will tell container that yes you can adjust your height
Your concept can be cleared by how actually widgets parent child relationship works i.e in brief
basically If am a child I will ask my parent okay what is my size so since my parent if it has a size it will bound me but if it doesnt has a size it will ask its parent okay tell me what space should I take and it goes on. Expanded and Flexible says that okay you can adjust yourself instead of being Fixed.
Flexible(
child: Container(
margin: EdgeInsets.only(left: 10.0,right: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${dataBookTitleSearch1[index]} ', style: kGoodSearchResultTextStyle, textAlign: TextAlign.left,),
SizedBox(
height: 10.0,
),
Text('${dataBookAuthorSearch1[index]}', style: kGoodSearchResultTextStyle,textAlign: TextAlign.left),
SizedBox(
height: 10.0,
),
Text('${dataBookExtensionSearch1[index]} ', style: kGoodSearchResultTextStyle,textAlign: TextAlign.left),
SizedBox(
height: 20.0,
),
Container(
width: 80.0,
height: 40.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Colors.white
),
child: Padding(
padding: const EdgeInsets.only(left:20.0,top: 12.0),
child: Text('Read'),
),
),
],
),
),
)

How to send Pointer events to Lower children in Stack

As the title says, when using Stacks in flutter, only the "last" rendered children can be interacted with if that child overlaps all other children. In my application i have a ListWheelScrollView which is contained in a Stack, and afterwards "styled" with gradients that lie on top of the ScrollView.
This makes more sense when given an example.
There is an existing issue on almost this exact situation here: Flutter- GestureDetector not working with containers in stack
However, it assumes you are working with a gesture detector.
Stack(children: <Widget>[
Container(
height: 250,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: _style.fontSize * 1.5,
child: ListWheelScrollView.useDelegate(
controller: fixedExtentScrollController,
physics: FixedExtentScrollPhysics(),
itemExtent: _style.fontSize * 1.5,
childDelegate: ListWheelChildLoopingListDelegate(
children: hours
.map((hour) => hour < 10
? Text(
"0$hour",
style: _style,
)
: Text(
"$hour",
style: _style,
))
.toList())),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
":",
style: _style,
),
SizedBox(
height: 25,
)
],
),
Container(
width: _style.fontSize * 1.5,
child: ListWheelScrollView.useDelegate(
physics: FixedExtentScrollPhysics(),
itemExtent: _style.fontSize * 1.5,
childDelegate: ListWheelChildLoopingListDelegate(
children: minutes
.map((minute) => minute < 10
? Text(
"0$minute",
style: _style,
)
: Text(
"$minute",
style: _style,
))
.toList())),
),
],
),
),
Container(
height: 250,
child: Column(
children: <Widget>[
Container(
height: 75.3,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.white.withOpacity(0.1),
Theme.of(context).scaffoldBackgroundColor
])),
),
Center(
child: Container(
height: 83.3,
width: 220,
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFFc0ccd4), width: 5),
))),
],
),
)
]),
The design works perfectly as expected, however i am no longer able of scrolling since the containers are on top of the scroll widget.
Any workarounds?
You only need to wrap all of your widgets that are not supposed to receive tap events in IgnorePointer widgets.
In the comments it was said that you should use AbsorbPointer, however, you do not want to catch tap events on the ignoring widgets.
In your case, you want to wrap your upper, upper as in top of the stack, Container in an IgnorePointer widget:
Stack(
children: <Widget>[
Container(...),
IgnorePointer(
child: Container(...),
),
],
)
Learn more.

Make container grow to fit width of sibling in column

I have two Container widgets in a Column, each containing a Text widget. I want the Container with the shortest text to expand to match the width of the other container containing the longer text. The container with the longer text should wrap the Text widget and its padding.
I can't get it to work without resorting to fixed widths on the containers:
return Column(
mainAxisSize: MainAxisSize.min,
children: [
// This container has a shorter text than its sibling, so it should expand
// its width to match its sibling/parent
Container(
alignment: Alignment.center,
width: 50, // I don't want this fixed width
decoration: BoxDecoration(color: Colors.orange, borderRadius: BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(4))),
child: Padding(
padding: const EdgeInsets.fromLTRB(8,4,8,4),
child: Text('short'),
)
),
// This container has a longer text, so it should decide the width of the
// other container (and of the parent Column)
Container(
alignment: Alignment.center,
width: 50, // I don't want this fixed width
decoration: BoxDecoration(color: Colors.orange, borderRadius: BorderRadius.only(bottomLeft: Radius.circular(4), bottomRight: Radius.circular(4))),
child: Padding(
padding: const EdgeInsets.fromLTRB(8,4,8,4),
child: Text('long text here'),
)
),
]
);
I've tried a couple of ways to solve it involving Expanded and Flexible, but they all result in the "red screen of death" (or at least "annoyance").
EDIT
Just to be clear - I want the Column to just wrap its content, i.e. adjust its width to the width of the containers. In summary - everything should be as narrow as possible, except for the container with the shortest text, which should instead be as wide as its sibling (the container with the longer text).
I saw your Fiddle on a comment. And what you need is IntrinsicWidth.
IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// This container has a shorter text than its sibling, so it should expand
// its width to match its sibling/parent
Padding(
padding: const EdgeInsets.symmetric(vertical: 1.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Text(
'short',
textAlign: TextAlign.center,
),
),
),
),
// This container has a longer text, so it should decide the width of the
// other container (and of the parent Column)
Padding(
padding: const EdgeInsets.symmetric(vertical: 1.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Text(
'long text here',
textAlign: TextAlign.center,
),
),
),
),
],
),
),
You can use something like this to take the entire width of the Widget (make sure to be inside a MaterialApp and a Scaffold/Material child (home):
Wrap(
children: <Widget>[
Container(
color: Colors.red,
child: IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
color: Colors.black,
height: 200,
child: Align(
alignment: Alignment.bottomRight,
child: Text(
"Hello World",
style: TextStyle(color: Colors.white),
),
),
),
Container(
color: Colors.blue,
height: 100,
child: Align(
alignment: Alignment.topRight,
child: Text(
"Bottom Text Longer Text",
style: TextStyle(color: Colors.white),
),
),
),
],
),
),
),
],
)
The Align is not necessary, is just to showcase how the width actually works with "double.infinity" and moving a text to the bottom right or top right portion of it.