My Flutter desktop web app has complex ui that would be too tricky to make responsive. So instead I want to put it in a FittedBox that will simply shrink the whole app if the user makes the browser window smaller.
class CustomPage extends StatelessWidget {
final Widget child;
const CustomPage({
Key? key,
required this.child,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: GetPlatform.isDesktop
? FittedBox(
child: SizedBox(
width: Get.width,
height: Get.height,
child: Center(child: child),
),
)
: Text('Sorry! This was only meant for desktop.'),
);
}
}
But Get.width and WidgetsBinding.instance.window.physicalSize.width only get the initial window size. So if the app is started in a full screen browser then this works great, but if the app is started in a small browser it doesn't work. MediaQuery.of(context).size.width only gets the current screen size.
Is there a way of getting a desktop physical screen size?
you need to import
import 'dart:html';
then window.screen?.width and window.screen?.height
will give you physycal screen size
import 'dart:html';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) => MaterialApp(debugShowCheckedModeBanner: false, home: Home());
}
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: LayoutBuilder(builder: (context, c) {
return Center(
child: Text('${window.screen?.width} ${window.screen?.height}'),
);
}),
);
}
}
Related
i tried to check which platform that the app been used in flutter. followed this kIsWeb reference for checking it. this is the code that i used
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class ResponsiveLayout extends StatelessWidget {
final Widget mobileScreenLayout;
final Widget webScreenLayout;
const ResponsiveLayout({
Key? key,
required this.mobileScreenLayout,
required this.webScreenLayout,
}) : super(key: key);
#override
Widget build(BuildContext context) {
if (kIsWeb) {
//WEB SCREEN
return webScreenLayout;
}
//MOBILE SCREEN
return mobileScreenLayout;
}
}
the result was backward. when i run it on web it gave me the mobileScreenLayout and when i run it on emulator it gave me the webScreenLayout. tried to swap both webScreenLayout with the mobileScreenLayout and they work how supposedly with what i want. is there any problem with that or it's ok?
this the link i saw the kIsWeb
https://stackoverflow.com/a/57965689/18627424
Please check mobileScreenLayout and webScreenLayout. I think you added wrong text in these widgets by mistake. kIsWeb will definitely show web when you run it in web. You can also try
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text(
(kIsWeb)?'Hello World Web!':"hello world mobile",
style: Theme.of(context).textTheme.headline4,
);
}
}
I need to calculate the height of a child widget before its parent renders.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: CustomAppbar(
widget: Text(
'This is a tex',
),
),
),
);
}
}
The above code just call a Widget CustomAppbar, which receives as parameter a TEXT widget
class CustomAppbar extends StatelessWidget implements PreferredSizeWidget {
final Widget? widget;
const CustomAppbar({
Key? key,
this.widget,
}) : super(key: key);
#override
Size get preferredSize => const Size.fromHeight(130.0);
#override
Widget build(BuildContext context) {
return ClipPath(
clipper: HeaderCustomClipper(),
child: ColoredBox(
color: Color.fromRGBO(255, 191, 14, 1),
child: Column(
children: [
_AppBar(),
if (widget != null) widget as Widget,
],
),
),
);
}
}
The above code just is a customAppbar, I want the height of the child widget (widget) to be captured before the CustomAppbar renders.
If I pass a text, it should be seen like that:
If I don't pass anything, it should be seen like that:
to achieve that you can use GlobalKey -> BuildContext -> RenderBox -> widget-> global position & rendered size.
please check this below link
https://stackoverflow.com/a/49650741/17180860
While nesting two Transform widgets, child widget (I.E. a picture) is disappearing in some cases.
It happens with Animation and AnimatedBuilder as well.
Conditions for reproducing:
Wide screen resolution only.
Flutter Web with HTML web renderer only (Not Android nor Flutter Web with CanvasKit)
Flutter 2.10.2
Minimal reproduce:
Create new folder flutter_web_bug
Open terminal inside that folder and execute flutter create .
Replace ./lib/main.dart contents with the following code
Open terminal and execute flutter run -d chrome --web-renderer html
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter web bug',
home: MyHomePage(title: 'Flutter web bug'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double angle = 0.0;
#override
void initState() {
super.initState();
Timer.periodic(const Duration(milliseconds: 20), (timer) {
setState(() {
angle += 0.01;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Transform(
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(pi * angle),
alignment: Alignment.center,
child: Align(
alignment: Alignment.center,
child: Container(
color: const Color(0xffaaffff),
child: Transform(
alignment: Alignment.center,
transform: Matrix4.identity()..rotateY(pi),
child: Image.network('https://docs.flutter.dev/assets/images/dash/dash-fainting.gif'))))),
));
}
}
Demonstration:
The issue seems to be with Image.network() where the image is rebuilding. I tested using the cached_network_image library and was able to get the image to stay rendered while animating. Hopefully this helps!
The code snippet below is how I generate my page. I detect the screenWidth and screenHeight and then use these values to detect if the page should be displayed in portrait or landscape.
The two factions return data type of Scaffold and the appropriate layout is rendered depending on screen orientation.
class UserInstructions extends StatefulWidget {
const UserInstructions({Key? key}) : super(key: key);
#override
_UserInstructionsState createState() => _UserInstructionsState();
}//***************** class UserInstructions ends **************************
class _UserInstructionsState extends State<UserInstructions> {
#override
Widget build(BuildContext context) {
double screenWidth = (MediaQuery.of(context).size.width) ;
double screenHeight = (MediaQuery.of(context).size.height);
if (screenWidth < screenHeight) { // we are in portrait mode
return portraitLayout();
}
else {//( screenWidth > screenHeight) we are in landscape mode
return landscapeLayout();
}//else( screenWidth > screenHeight) we are in landscape mode
}//********************** Widget build ends *****************************
}//*************** class _UserInstructionsState ends **********************
I have created 2 functions:-
Scaffold portraitLayout() {
return Scaffold (
body: Centre(
.
.
.
}//*********** function portraitLayout ends************
Scaffold landscapeLayout() {
return Scaffold (
body: Centre(
.
.
.
}//**************** function landscapeLayout ends *******************
these functions provide the differing screen layouts for the two orientations.
When I rotate the simulator screen between orientations I would like the new orientation layout to take effect. Only way I can achieve this at the moment is by using hot reload. I have tried using
double screenWidth = (MediaQuery.of(context).size.width) inside my functions but the compiler complains giving me a context error 'JsObject' can't be assigned to the parameter type 'BuildContext'.
I’m at a loss any help would be appreciated.
There is a Material Widget called layout builder that can help you achieve this very efficiently.
The sample code is as follows.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatelessWidget(),
);
}
}
/// This is the stateless widget that the main application instantiates.
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('LayoutBuilder Example')),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (MediaQuery.of(context).orientation ==
Orientation.portrait) {
return _buildNormalContainer();
} else {
return _buildWideContainers();
}
},
),
);
}
Widget _buildNormalContainer() {
return Center(
child: Container(
height: 100.0,
width: 100.0,
color: Colors.red,
),
);
}
Widget _buildWideContainers() {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
height: 100.0,
width: 100.0,
color: Colors.red,
),
Container(
height: 100.0,
width: 100.0,
color: Colors.yellow,
),
],
),
);
}
}
You can find the documentation here. Documentation
I am confused what the width of the slider widget is: I have a stack and added an align widget that contains a slider.
Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: OptionsBar(),
),
],
),
),
);
}
}
class OptionsBar extends StatefulWidget {
const OptionsBar({Key? key}) : super(key: key);
#override
_OptionsBarState createState() => _OptionsBarState();
}
class _OptionsBarState extends State<OptionsBar> {
double progress = 0.0;
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10),
child: Row(
children: [
Slider(
value: progress,
onChanged: (double newValue) => setState(() => progress = newValue),
)
],
),
);
}
}
The code works but places the slider in the middle of the screen. However, if I give the widget that contains the slider a height than the bar remains at the bottom. So, does that mean that a slider takes up the entire height that it can get? Seems a little bit strange or am I getting something wrong?
You have set alignment to bottom that's why when you set height of widget it remains on the bottom. Try to set height to the widget that containing slider and change alignment.