Problem with scrolling body of my Flutter web page - flutter

I'm trying to do my first flutter web page.
I want make navigation app bar on the top and scrollable area with pictures and text below.
And I have a problem with renering my page. Body of my page is not scrolling and it overflows at the bottom. What I'm doing wrong?
Here is my sample code:
#override
Widget build(BuildContext context) {
return Column(
children: [
TopBar(),
SingleChildScrollView(
child: Column(
children: [
Container(
height: 300,
color: Colors.red,
),
Container(
height: 300,
color: Colors.green,
),
Container(
height: 300,
color: Colors.black,
)
],
),
)
],
);
}
}

You can combine Column and ListView like:
#override
Widget build(BuildContext context) {
return Column(
children: [
AppBar(),
Expanded(
child: ListView(
children: [
Container(
height: 300,
color: Colors.red,
),
Container(
height: 300,
color: Colors.green,
),
Container(
height: 300,
color: Colors.black,
)
],
),
),
],
);
}

Related

How to center one element and place the second element next to it

In my layout I have two Widgets in a row, a text and a button.
How can I achieve something like below, where only the Text is centered, and the icon is simply next to it?
---------------------------
Text *
---------------------------
Using Row would center all the contents and would output something like
---------------------------
Text *
---------------------------
Tried: Row(children:[widget1, widget2], mainAxisAlignment: MainAxisAlignment.center);
But this centers both items, causing the text to look off-centered.
You can use CompositedTransformTarget and CompositedTransformFollower as mentioned on comment section by pskink.
class AppPT extends StatelessWidget {
const AppPT({super.key});
#override
Widget build(BuildContext context) {
final LayerLink _layerLink = LayerLink();
return Scaffold(
body: Column(
children: [
Stack(
children: [
Align(
child: CompositedTransformTarget(
link: _layerLink,
child: Container(
color: Colors.red,
width: 100,
height: 60,
alignment: Alignment.center,
child: Text("btn"),
),
),
),
CompositedTransformFollower(
link: _layerLink,
targetAnchor: Alignment.centerRight,
followerAnchor: Alignment.centerLeft,
child: Container(
color: Colors.cyanAccent,
width: 12,
height: 12,
alignment: Alignment.center,
child: Text("*"),
),
),
],
)
],
),
);
}
}
There are few tricks I can think of,
You can use Stack widget with Position.
including another widget on right by applying opacity(invisible) on current snippet.
using transform will be handle if you know the width of the widget.
Transform.translate(
offset: Offset(20 / 2, 0), //20 is the * box size
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.red,
width: 100,
height: 60,
alignment: Alignment.center,
child: Text("btn"),
),
Container(
color: Colors.green,
width: 20,
height: 20,
child: Center(child: Text("*")),
),
],
),
),
Place text and second widget inside row then put the row inside container with alignment center and use SizedBox for spacing between widget instead of Padding Widget.
Container(
color: Colors.green,
alignment: Alignment.center,
height: 100,
child: Row(
mainAxisSize: MainAxisSize.min,
children: const [
Text("Text"),
SizedBox(width: 10),
Text("*"),
],
),
);

I need to set my box height flexible to fit any size of screen

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

Widget on a widget with Centering

I want to put a widget onto other's view.
Here is what I did
In normal version without countdown timer, there is no whitespace inside the screen. It is %50 %50 divided by colours(red and blue).
What I want to do is adding that countdown timer without creating whitespace. Directly adding it onto those colours on the center.
I saw that with Stack it is possible to do. I tried it but couldn't remove the white area.
Here is my code:
#override
Widget build(BuildContext context) {
return Scaffold(
body: new Column(
children: [
Expanded(
flex: 40,
child: new Container(
width: double.infinity,
child: new Column(
children: <Widget>[
box1 = new Expanded(
flex: boxSize1,
child: InkWell(
onTap: () {
clickBox1();
}, // Handle your callback
child: new Container(
alignment: Alignment.topCenter,
color: colorRandom,
),
),
),
TimeCircularCountdown(
unit: CountdownUnit.second,
countdownTotal: 3,
onUpdated: (unit, remainingTime) => print('Updated'),
onFinished: () {
setState(() {
visibility = false;
});
},
),
box2 = new Expanded(
flex: boxSize2,
child: InkWell(
onTap: () {
clickBox2();
}, // Handle your callback
child: new Container(
alignment: Alignment.topCenter,
color: color,
),
),
),
],
),
),
),
],
),
);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Column(
children: [
Expanded(
child: Container(
color: Colors.blue,
)),
Expanded(
child: Container(
color: Colors.red,
)),
],
),
Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: Colors.white,
),
// use your countdown timer widget in child
),
)
],
),
);
}

Flutter - center button

I'm creating a UI with 5 buttons. One of them should be center and its width should be 50% of the screen. The height should be the same size (it should be a circle). I tried with MediaQuery.of(context).size.width but it doesn't work.
This is the closest I got:
The code is:
Widget _playButton() {
return FractionallySizedBox(
widthFactor: 0.5,
heightFactor: 0.5, // I know this is wrong
child: Container(
alignment: new FractionalOffset(0.0, 0.0),
color: Colors.red,
/*decoration: new BoxDecoration(
color: hexToColor('#E8532E'),
shape: BoxShape.circle,
),*/
child: Center(
child: Text(
"PLAY",
style: TextStyle(fontSize: 20.0, color: Colors.white),
),
),
),
);
}
The container where I have this button:
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
body: new Stack(
alignment: AlignmentDirectional.center,
children: <Widget>[_myScreenOptions(), _playButton()],
),
),
);
}
Obviously, the rest of the buttons should be clickable.
If you wanna create a circular button, you don't have to worry about width & height, giving only one size is enough... or you can use FractionallySizedBox, as you already did.
Code output:
Sample code:
import 'package:flutter/material.dart';
class SampleCenterButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
_myScreenOptions(),
_playButton(),
],
),
),
);
}
_playButton() {
return GestureDetector(
onTap: () {
print("Play game");
},
child: FractionallySizedBox(
widthFactor: 0.5,
child: Container(
// defining one dimension works as well, as Flutter knows how to render a circle.
// width: MediaQuery.of(context).size.width/2,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Center(
child: Text(
"PLAY",
style: TextStyle(fontSize: 30, color: Colors.white),
),
),
),
),
);
}
_myScreenOptions() {
return Column(
children: <Widget>[
buildRow([
buildOption(Color(0xff1D4554), Icons.person, "Teams"),
buildOption(Color(0xff229B8D), Icons.folder_open, "Pets"),
]),
buildRow([
buildOption(Color(0xffE7C16A), Icons.videogame_asset, "Modes"),
buildOption(Color(0xffF2A061), Icons.settings, "Options"),
]),
],
);
}
Widget buildOption(Color bgColor, IconData iconData, String title) {
return Expanded(
child: Container(
color: bgColor,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
iconData,
size: 80,
),
Text(
title,
style: TextStyle(fontSize: 30),
),
],
),
),
);
}
buildRow(List<Widget> buttons) {
return Expanded(
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: buttons,
),
);
}
}

How to put view above the list view?

I have a listview which is equally divided into two parts(act as a background) How can i put a view above it( 100*100 w*h )?(This box should center align & top of root)
here is my tried code -
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: <Widget>[
Container(
width: ((context.findRenderObject() as RenderBox).size.width),
height: ((context.findRenderObject() as RenderBox).size.height)/2,
color: darkGreen,
),
// SizedBox(width: 10,),
Container(
width: ((context.findRenderObject() as RenderBox).size.width),
height: ((context.findRenderObject() as RenderBox).size.height)/2,
color: Colors.grey,
),
],
),
);
}
}
First of all, you don't need this line:
((context.findRenderObject() as RenderBox).size.width)
you can replace it with:
double.infinity
and it will take the maximum width the parent Widget can allow.
as for your question, you can wrap your ListView in a Stack:
Container(
width: double.infinity,
height: double.infinity,
child: Stack(
children: <Widget>[
ListView(
children: <Widget>[
Container(
width: double.infinity,
height:
((context.findRenderObject() as RenderBox).size.height) / 2,
color: darkGreen,
),
// SizedBox(width: 10,),
Container(
width: double.infinity,
height:
((context.findRenderObject() as RenderBox).size.height) / 2,
color: Colors.grey,
),
],
),
//place your desired widget here
],
),
),