I am a junior developer currently under development in Flutter.
I am currently working on a tablet-only UI and hope it will be compatible with the web environment.
So far, there has been no problem, but there has been a problem with the SlidingUpPanel.
Before applying the SlidingUpPanel, the UI is as follows.
I wanted to apply SlidingUpPanel to the red box space at the bottom of this screen.
So I created the code as follows, and the Widget Tree is shown in the following picture.
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Row(
children: [
Expanded(
flex: 1,
child: SlidingUpPanel(
panel: Text('test'),
body: Column(
children: [
SizedBox(
height: 80.0,
child: HomePageAppBar(),
),
Container(
height: 70.0,
color: Color(0xFFF4F4F4),
child: Row(
children: [
SizedBox(
width: 10.0,
),
Text(
'리스트',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
),
),
],
),
),
Expanded(
flex: 1,
child: DatePickerContainer(),
),
],
),
),
),
SizedBox(
width: 338.0,
child: Container(
color: Color(0XFFF0F0F0),
),
),
],
),
),
);
}
}
However, after applying SlidingUpPanel, the screen changed strangely as follows...
What's the problematic part in my code?
Edit 1
I used Stack Widget and succeeded in getting SlidingUpPanel without breaking the overall UI as follows.
The code is as follows.
Expanded(
flex: 1,
child: Stack(
children: [
DatePickerContainer(),
SizedBox(
width: _getCurrentWindowWidth(context) - 338.0,
child: SlidingUpPanel(
panel: SizedBox(
width: _getCurrentWindowWidth(context) - 338.0,
child: Center(
child: Text('test'),
),
),
),
),
],
),
),
However, when the SlidingUpPanel is dragged up, it appears that the actual width is the same as the width of the entire screen, but only the visible width is cut off as follows:
Related
This is my first question and I'm new in Flutter. I searched a lot but I did not find any suitable answers.
Flutter: I need to set my box height flexible to fit any size of screen. I also need to fit my last box to the right side of screen to fit any screen. I also mentioned my problem in the image of screen. Kindly help. I'm adding my code here.
Output and requirement of my code
void main() {
runApp(const Challange2());
}
class Challange2 extends StatelessWidget {
const Challange2({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.blueGrey,
body: SafeArea(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 850.0,
width: 100.0,
color: Colors.amberAccent,
child: Text(
'This box height should be flexible according to screen size',
style: TextStyle(color: Colors.black, fontSize: 25),
),
),
const SizedBox(
width: 65,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 100.0,
width: 100.0,
color: Colors.deepPurpleAccent,
child: Text(
'Text2',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
Container(
height: 100.0,
width: 100.0,
color: Colors.deepOrangeAccent,
//Flexible(
child: Text(
'Text3',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
//),
],
),
const SizedBox(
width: 65,
),
Container(
height: 850.0,
width: 100.0,
color: Colors.blue,
child: Text(
'This box need to be right alignment and height should be flexible according to screen size',
style: TextStyle(color: Colors.black, fontSize: 25),
),
// child: const Align(
// alignment: Alignment.topCenter,
),
],
),
),
),
//),
//return Container();
);
}
}
To adapt to screen height, you can set height of containers to double.infinity,
To keep rigth container aligned to the right, use expanded in the center row child, in order to make this widget grow or shrink as needed.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Row(children: [
Container(
width: 100,
height: double.infinity,
color: Colors.red,
child: Text(
'This box height should be flexible according to screen size'),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 50,
height: 50,
color: Colors.green,
),
Container(
width: 50,
height: 50,
color: Colors.yellow,
),
]),
),
Container(width: 100,
height: double.infinity,
color: Colors.blue, child:Text("Right Panel"),),
]),
);
}
}
LayoutBuilder() Provides a way to get the actual screen size dynamically and allows you to calculate relative sizes: Youtube - Flutter: LayoutBuidler
Generally when using Rows and Columns you can use Expanded widgets to have relative instead of absolute sizes:
Row(
children: [
Expanded(flex: 1, child: Container()), // This will take up 1 third of the screen
Expanded(flex: 2, child: Container()), // This will take up 2 thirds of the screen
]
),
Expanded(flex: 1, child: Container()),
Expanded(flex: 1, child: Container()),
I'm building an AR app with Flutter and using the ar_flutter_plugin.
The position of the AR widget seems to be fixed to the top left and it doesn't move anywhere else. Whatever the other widgets in the tree, doesn't change anything. It's always at top left corner (see image).
It works with a dummy widget just fine (compare second img).
Child Ar widget
Widget build(BuildContext context) {
return SizedBox(
width: widget.width,
height: widget.height,
child: Column(
children: [
Expanded(
child: Column(children: [
Expanded(
child: ARView(
onARViewCreated: onARViewCreated,
planeDetectionConfig:
PlaneDetectionConfig.horizontalAndVertical,
),
),
Align(
alignment: Alignment(1, 1),
child: FloatingActionButton(onPressed: takePicture))
]),
),
],
));
}
Parent Widget
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Title'),
),
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
body: SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Stack(
children: [
Container(
width: 350,
height: 350,
child: ObjectsOnPlanesWidget(
// child: custom_widgets.ArPlaceholder(
width: double.infinity,
height: double.infinity,
modelUrl: widget.modelUrl,
),
),
Align(
alignment: AlignmentDirectional(-0.23, -0.92),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(8, 24, 8, 24),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color:
FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: InkWell(
onTap: () async {
Navigator.pop(context);
},
child: Icon(
Icons.chevron_left,
color: Colors.black,
size: 24,
),
),
),
Text(
'Try On',
style: FlutterFlowTheme.of(context).bodyText1,
),
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color:
FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.share_outlined,
color: Colors.black,
size: 24,
),
),
],
),
),
),
Align(
alignment: AlignmentDirectional(0, 0.95),
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.photo_camera,
color: Colors.black,
size: 24,
),
),
),
],
),
),
),
);
}
I want to put the camera in the background and put other widgets (such as photo-taking-button) on top of it.
How do I reposition it into a container? At least under the App Bar?
Logically this should have worked, what i would suggest you try would be to first have a SafeArea widget.
SafeArea(
child: build(buildContext),
),
I had a similar issue in the past and using this solved it.
Also, there seems to be an open issue which seems related to this with the following possible solution :
With Flutter 2.10.5. it works without problems. This seems to be a Flutter 3 problem.
The way platforms views are rendered was changed in the 3.0 release.
probably same issue:
flutter/flutter#106246
explained here:
flutter/flutter#103630
I hope this will be fixed in new Flutter 3 releases soon.
And also this
I try the master channel Flutter v3.1.0-0.0.pre.1372 and the issue is fixed there.
Fixed will come to a stable channel soon with Flutter v3.1.0.
Also, I am not sure why are you using SizedBox as your parent widget.
Why not try a basic Container instead?
Good luck, Let me know if I can help with anything else
Hi trying to figure out why my hamburger is getting misaligned when i add another Expanded() code within the body.
I tried to follow this url to develop a hamburger menu and responsive for all platforms at once.
Flutter Blog
Below is the code that i tried where i added Expanded() below the Row()
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
return Scaffold(
key: _scaffoldKey,
drawer: AppDrawer(),
body: Row(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: IconButton(
icon: Icon(Icons.menu, size: 30),
onPressed: () {
_scaffoldKey.currentState.openDrawer();
}),
),
],
),
Expanded(
child: Container(
width: width,
child: Column(
children: [
Expanded(
child: Lottie.network(
'https://assets2.lottiefiles.com/datafiles/6WfDdm3ooQTEs1L/data.json'),
),
Expanded(
child: Column(
children: [
Flexible(
child: Text(
"Multivariate Testing",
style: GoogleFonts.montserrat(
fontSize: 50,
),
),
),
SizedBox(
height: 10,
),
Flexible(
child: Text(
'Run experiments to make key flows more effective.',
style: GoogleFonts.montserrat(
fontSize: 25,
),
),
),
SizedBox(
height: 35,
),
// ignore: deprecated_member_use
TextButton(
onPressed: () {},
child: Text(
'Create Experiment',
style: GoogleFonts.montserrat(
fontSize: 20,
),
),
)
],
),
),
],
),
),
)
],
),
);
}
}
and the output that i am seeing from mobile view. Appreciate any help. Sorry for too big screenshot!
This is because of the default functionality of Row.
So change your first child for your top level Row to this,
Scaffold(
key: _scaffoldKey,
drawer: AppDrawer(),
body: Row(
children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.all(16),
child: IconButton(
icon: Icon(Icons.menu, size: 30),
onPressed: () {
_scaffoldKey.currentState.openDrawer();
})),
),
Expanded( ...... rest of your code
Here, we are using the Align widget with alignment: Alignment.topCenter.
Align widget takes the entire available space in the parent and then depending on the alignment property, aligns it't child inside it.
So, saying Alignment.topCenter will place it at the top vertically and middle horizontally.
Using an AppBar will unnecessarily complicate your situation since now, the AppBar is going to take up space a the top, but in your case, you want your Lottie view to be visible at the top, so it will overlap.
Because Expanded fills up the whole space and that's why your hamburger is getting misaligned.
Why don't you try using appbar for the hamburger?
I'm building a product detail page. As the following piece of code and image shown, when there is a lot of content in the description part, the bottom overflow will occur. I'm wondering how to make the page scrollable, I've tried wrapping the Stack with SingleChildScrollView, but this is definitely not working in my case here. Can anyone help me with that? Thank you very much!!!!!
class DetailsScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
buildBody("path/to/image", size),
],
),
);
}
Positioned buildBody(String imagePath, Size size) {
return Positioned.fill(
child: Column(
children: [
Expanded(
child: Container(
padding: EdgeInsets.symmetric(vertical: 60, horizontal: 30),
color: Colors.green,
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: Hero(
tag: 1,
child: Image.asset(
imagePath,
width: size.width * 0.7,
),
),
),
],
),
),
),
Expanded(
child: Container(
color: Colors.white,
child: Column(
children: [
SizedBox(
height: 100,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 20,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(),
SizedBox(
width: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Anvesha Shandilya',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16),
),
Text(
'Owner',
style: TextStyle(
color: fadedBlack,
),
),
],
),
Expanded(child: Container()),
Text(
'Dec 16, 2020',
style: TextStyle(
color: fadedBlack,
fontSize: 12,
),
),
],
),
),
SizedBox(
height: 30,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 20,
),
child: Text(
'A lot of content..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................',
style: TextStyle(
color: fadedBlack,
height: 1.7,
),
),
),
],
),
),
),
],
),
);
}
}
Error: Bottom Overflowed
To reproduce: Change the path/to/image, to this: A image can be used with the code:
tl;dr remove Expanded widgets -> remove Stack -> replace Column with ListView (for scrollability)
Start by removing Expanded widgets from the tree as you don't really need them. If possible, you should use mainAxisAlignment and crossAxisAlignment to position your widgets. That's exactly how you should handle placing the date next to user's name.
Expanded documentation states with which widgets you can use it:
Creates a widget that expands a child of a Row, Column, or Flex so
that the child fills the available space along the flex widget's main
axis.
Then remove Stack widget. If you don't then it will still work as Stack tries to get as big as its positioned children so it will just get as big as the Column you have inside. It's redundant.
Last but not least, replace Column with ListView. Column doesn't really care about whether it's overflowing or if it's being rendered. So if you create a Column that is bigger than the screen, it will simply display it which will cause the overflow. To fix that you could wrap it SingleChildScrollView, but I think it's more appropriate to just use ListView instead.
Here's an amazing explanation of layout system in Flutter: https://flutter.dev/docs/development/ui/layout/constraints
In HTML creating a page that is divided into 2 columns that span 100% of the screen height is easy
<div id="row">
<div id="column1" style="width:75%; height:100%"></div>
<div id="column2" style="width:25%; height:100%"></div>
</div>
Using Flutter this seems more complicated than it should be, i tried to achieve the above in a couple of ways: (The page's outline is CustomScrollView -> SliverToBoxAdapter -> Row -> Columns)
Using MediaQuery to set the columns' height as deviceSize.height. This failed because as the left column got bigger than the right column, the right column did not expand in size to match.
Using Expanded or Flexible (tight or loose) to try and expand the height. This did not work.
My question is how do i achieve 100% height and not 100vh height in Flutter web?
Edit:
This illustrates the problem, the right column is not expanding in size to match the left column.
CustomScrollView(
slivers: <Widget>[
SliverFillRemaining(
child: Container(
color: Colors.purple,
child: SingleChildScrollView(
child: Row(
children: <Widget>[
Container(
color: Colors.blue,
child: Column(
children: <Widget>[
Text("test"),
SizedBox(height: 300),
Text("test"),
SizedBox(height: 300),
Text("test"),
SizedBox(height: 300),
Text("test"),
SizedBox(height: 300),
],
),
),
Container(
color: Colors.yellow,
child: Column(
children: <Widget>[Text("test")],
),
),
],
),
),
),
),
],
);
Not sure if this is what you want. But based on your statement I think you are looking for two column layout as in here and as shown below in the image.
Following is the code for the same. You can adjust the flex value in the Expanded widget to acquire the required screen width ratio. but if you want to adjust the width each columns like using a drag handle or so, then this alone wont suffice.
import 'package:flutter/material.dart';
class FullHeightDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: <Widget>[
Expanded(
flex: 4,
child: Container(
color: Colors.red,
child: Center(
child: Text(
'Column-1',
style:
TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
),
),
),
Expanded(
flex: 1,
child: Container(
child: Container(
color: Colors.teal,
child: Center(
child: Text(
'Column-2',
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
),
),
)
],
));
}
}
Specifying the height using MediaQuery inside a Scrollable widget could help
Following code places the columns inside a SingleChildScrollableView widget and specifies the height of the container based on MediaQuery to achieve the same. Will this help.? The LayoutBuilder is only there to show that the using the height from its constraints could also lead to error since in this case its height is also infinite.
import 'package:flutter/material.dart';
class FullHeightDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: LayoutBuilder(
builder: (context, constraints) {
var size = MediaQuery.of(context).size;
return Container(
child: Row(
children: <Widget>[
Container(
height: size.height,
// height: constraints.maxHeight,
width: constraints.maxWidth / 2,
color: Colors.red,
child: Center(
child: Text(
'Column 1',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
),
Container(
color: Colors.green,
height: size.height,
// height: constraints.maxHeight,
width: constraints.maxWidth / 2,
child: Center(
child: Text(
'Column 2',
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
)
],
),
);
},
),
);
}
}