I have 2 widget in stack. One of them is aligned in center. And the widget which is on the top is other stack. And I want show second widget with first widget's top and left position. Here is the explain:
The yellow area is my stack. And first widget is setted like Center(child: myFirstWidget). My second widget is referenced from here it's a resizable widget so it's an another stack and it's childs are "positioned". So I need to set top and left value for initialize. But my main stack filled page So when I set my second widget's top and left to 0. It's shown as below.
But I want to show align it to centered child's top like:
My code snip:
child: Container(
color: Colors.red,
child: Stack(
children: [
Center(
child: Image.file(
File("myfilepath"),
),
),
ResizableWidget(
child: Container(
color: Colors.blue,
),
),
],
),
),
You can adjust the position of the widgets with the Position widget like this:
Positioned(
child: ResizableWidget(
child: Container(
color: Colors.blue,
),
),
top: 80,
right: -5,
),
The value of top and right are just random values, you should check what works for you!
You should make Center the parent of the Stack.
The Stack will be positioned at the center of its parent because of Center, it will get the dimensions of its biggest childs (height and width) and will position other childs according to the alignment value.
Edit : I modified the code to include a placeHolder image. Here I gave it a 6000x2000 size but you can change it to whatever value you want. Code is working as expected, see capture below.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Stack(
alignment: AlignmentDirectional.topStart,
children: [
Image.network('https://via.placeholder.com/6000x2000'),
SizedBox(
height: 50,
width: 50,
child: Container(
color: Colors.green,
))
],
),
),
);
}
Related
as you can see at the image above, I have a red container stick on the top (right below the app bar). here is the code I use
CustomScrollView(
slivers: [
SliverAppBar(),
_buildStack(),
]
),
Widget _buildStack() {
return SliverStack(
children: [
// I have other widgets here ..
SliverPositioned(
bottom: 0, // <-- I have set the bottom to be zero
child: SliverToBoxAdapter(
child: _buildRedBox(),
),
],
)
}
Widget _buildRedBox() {
return Container(
width: double.infinity,
height: 50,
color: Colors.red,
);
}
I am using sliver tool package so I can access SliverStack and SliverPositioned.
as you can see, I have set the bottom to be zero. but the red box is still on the top. I need to make the red box at the bottom of the screen inside my SliverStack. how to do that ?
Use SliverFillRemaining widget instead of SliverPositioned widget.
SliverFillRemaining will automatically size itself to fill the space between the bottom of the last list item and the bottom of the viewport
SliverFillRemaining(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildRedBox(),
],
),
),
I have a PageView with Stack children. those Stack widgets contain transparent containers that controlls the opacity level relative to the scroll position.
the expense is that now I am unable to scroll what's in the background. what is the best way to add that layer and keep my backround scroll active.
Updating the Listview widget seems expensive as the opacity transion changes that is why I tried to keep it separate
I have something like this
Stack(children: [
Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: ListView..., // the listView I am trying to scroll
),
),
),
currIndex == 1 ? MainCardTransitionContainer() : Container(), // the layer with opacity
]),
Try IgnorePointer:
Stack(children: [
Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: ListView..., // the listView I am trying to scroll
),
),
),
currIndex == 1 ? IgnorePointer(ignoring: true, child:MainCardTransitionContainer(),) : Container(), // the layer with opacity
]),
Try this
Stack(children: [
currIndex == 1 ? MainCardTransitionContainer() : Container(), // the layer with opacity
Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: ListView..., // the listView I am trying to scroll
),
),
),
]),
It's because the top widget of stack is kept at background and last widget is placed in foreground.
In short keep background element at top of stack
What is the best way to build a "nested bottom sheet" which behaves like this:
https://dribbble.com/shots/14139422-Mobile-banking-app-interactions?
Do I have to use NestedScrollView or CustomScrollView, or a completely different approach?
Update :
This is my result using SlidingUpPanel, but I still have two problems:
When sliding up the panel, the green and red containers stay behind the panel and do not scroll out of view at the top.
In landscape mode the containers are higher than the device, so this approach does not work. I need the panel to be attached to the bottom of the containers, so it is only visible when scrolling down.
Code:
SafeArea(
child: Scaffold(
body: SlidingUpPanel(
minHeight: MediaQuery.of(context).size.height - 479,
maxHeight: MediaQuery.of(context).size.height - 79,
panel: SingleChildScrollView(
child: Column(
children: [Text('Sliding Panel')],
),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 100,
color: Colors.green,
),
Container(
height: 300,
color: Colors.red,
)
],
),
),
),
),
);
Result:
I believe there is a Widget for what you want to do, since there is a widget for everything in Flutter. here is the link of the package
NOTE : you can also set minimum height of the widget when collapsed in order to control how much of the widget you can show when it is collapsed.
And here is the demo :
I have the following dial located at the center of my screen.
I have called three different part to construct this dial.
However it seems to be stuck in the center of my screen and I want to shift it to the top center portion. Ive tried changing the alignments but it doesn't seem to work.
This is my code:
This is the dependency I'm using: https://pub.dev/packages/flutter_neumorphic
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
pedometerOuterDial(context),
pedometerInnerDial(context),
Center(child: stepText()),
],
);
}
Widget stepText() {
return Text(
'4800\nSteps',
style: khomeStyle.copyWith(color: kOrange),
);
}
Widget pedometerOuterDial(context) {
final percentage = 30.0;
return Padding(
padding: const EdgeInsets.all(80.0),
child: Align(
alignment: Alignment.topCenter,
child: Neumorphic(
boxShape: NeumorphicBoxShape.circle(),
padding: EdgeInsets.all(10),
style: NeumorphicStyle(
depth: NeumorphicTheme.embossDepth(context),
),
child: CustomPaint(
painter: NeuProgressPainter(
circleWidth: 20,
completedPercentage: percentage,
defaultCircleColor: Colors.transparent,
),
child: Center(),
),
),
),
);
}
Widget pedometerInnerDial(context) {
return Align(
child: Neumorphic(
boxShape: NeumorphicBoxShape.circle(),
padding: EdgeInsets.all(80),
style: NeumorphicStyle(
color: Colors.white,
depth: NeumorphicTheme.depth(context),
),
),
);
}
Also I haven't used Media Query here for any of the dials, so will that be an issue for displaying on other devices?
Since you are using a stack widget, the best way to do this is to use a positioned widget. You can place the widget on top by wrapping it with Positioned and setting the top property to 0.
Here is an example:
Positioned(
top:0,
child:YourWidget(),
),
Alignment won't work for the stack widget because it only aligns the items when there are extra space around it. Example: It works in a Column or Row since they occupy space and allow the widgets inside it to be placed and move around the occupied space.
I want to overlap the bottom edge of a widget with another widget so that it looks like this:
I am using a stack to position the arrow button over the card. At the moment I just set the position with an invisible box above it. The issue is that this method only works for that exact resolution - it should be screen size independent.
The necessary code for the widget:
Stack(
children: <Widget>[
Container( //background
height: 100,
width: 100,
),
FloatingActionButton(
child: Icon(Icons.arrow_forward),
onPressed: () {},
)
],
)
Update - April 2021
You can no longer use the overflow property in a Stack widget as it has been deprecated. Use clipBehaviour instead. Source: Flutter docs
You can use the Stack and Positioned widget to achieve this UI.
Stack(
clipBehavior: Clip.none,
children: <Widget>[
Container(
color: Colors.amber,
height: 150,
width: 150,
),
Positioned(
child: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
print('FAB tapped!');
},
backgroundColor: Colors.blueGrey,
),
right: 0,
left: 0,
bottom: -26,
),
],
),
Output:
Update - March 2022
The Area which is outside of Stack won't be clickable due to the platform limitation, and that is how the Stack widget works.
You can learn more about the same in this issue.
As of November 2019 I'd like to add a second solution:
Using package: https://pub.dev/packages/assorted_layout_widgets
var widget1 = ...;
var widget2 = ...;
ColumnSuper(
children: [widget1, widget2],
innerDistance: -26,
);
The difference from this solution to the one using Stack is that Positioned widgets in a Stack don't occupy vertical space. However, the ColumnSuper will have the size of all of its children widgets. Note I am the author of this package.
You could try my package (signed_spacing_flex). It's exactly the same as a normal Column (or Row and Flex). But it lets you set negative spacing which causes its children to overlap. You can also set which children should be on top when they overlap.
In your case it would be something like:
SignedSpacingColumn(
spacing: -16.0,
stackingOrder: StackingOrder.lastOnTop,
children: [
Container(
height: 100,
width: 100,
color: Colors.red,
),
FloatingActionButton(
child: const Icon(Icons.arrow_forward),
onPressed: () {},
)
],
)
It works with expanded children if you need.