I need help, I am using flutter to make App will have 3 interfaces 1- Mobile application (portrait) 2- Tablet/iPad (portrait) 3- Tablet/iPad (Landscape)... during debugging stage this was working perfectly till I made the app release... now the App is detecting the Portrait mode of the tablet but does not change to landscape (it seems that the App is not detecting the landscape mode)...here is a copy from my code
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:url_launcher/url_launcher.dart';
import 'constants.dart';
import 'home_page.dart';
class ContactUs extends StatefulWidget {
ContactUs({required this.contactUsHeader, Key? key}) : super(key: key);
String contactUsHeader;
@override
_ContactUsState createState() => _ContactUsState(contactUsHeader);
}
enum ResultField { FeedBack, Subject }
class _ContactUsState extends State<ContactUs> {
_ContactUsState(this.contactUsHeader);
final String contactUsHeader;
final _fieldFeedBack = TextEditingController();
final _fieldSubject = TextEditingController();
FocusNode focusFeedBack = FocusNode();
FocusNode focusSubject = FocusNode();
List unchangedFields = [ResultField.FeedBack, ResultField.Subject];
String valueFeedBack = '';
String valueSubject = '';
bool userSetFeedBack = false;
bool userSetSubject = false;
//=====These parameters to make responsive font size
double SonyZRWidth = 360;
double SonyZRHeight = 592;
void listenerFieldFeedBack() {
if (focusFeedBack.hasFocus) {
try {
valueFeedBack = _fieldFeedBack.text;
userSetFeedBack = true;
} catch (e) {}
setState(() {});
}
}
void listenerFieldSubject() {
if (focusSubject.hasFocus) {
try {
valueSubject = _fieldSubject.text;
userSetSubject = true;
} catch (e) {}
setState(() {});
}
}
@override
void initState() {
super.initState();
// _fieldFeedBack.addListener(listenerFieldFeedBack);
// _fieldSubject.addListener(listenerFieldSubject);
}
void feedBackEmail() {
String encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
final Uri params = Uri(
scheme: 'mailto',
path: '[email protected]',
query: encodeQueryParameters(<String, String>{
'subject': valueSubject,
'body': valueFeedBack,
}),
);
launch(params.toString());
}
//===== This to activate the calculate button
bool activateSend() {
bool isActivated;
if (_fieldSubject.text != '' && _fieldFeedBack.text != '') {
isActivated = true;
} else {
isActivated = false;
}
return isActivated;
}
//===== This is to show the text of the missing fields
String missingFields() {
String tostText = '';
if (_fieldFeedBack.text == '' && _fieldSubject.text == '') {
tostText = 'Please enter the subject & your thoughts';
} else if (_fieldFeedBack.text == '') {
tostText = 'It seems that you did not share you thoughts with Us';
} else if (_fieldSubject.text == '') {
tostText = 'What about the subject.. please fill in the subject field';
}
return tostText;
}
void toastisMissing() =>
Platform.isIOS ? cupertinoAlertIsMissing() : toastIsMissingAndroid();
/// This is to determine between toast massage for android or Cupertino Alert Dialod for IOS.
//====== this is the imported toast massage for android
void toastIsMissingAndroid() {
Fluttertoast.showToast(
msg: missingFields(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
);
}
//====== this is the Cupertino alert Dialog for IOS
void cupertinoAlertIsMissing() {
showDialog(
context: context,
builder: (ctx) {
return CupertinoAlertDialog(
title: Text(missingFields()),
actions: [
CupertinoDialogAction(
child: const Text('Noted'),
onPressed: () => Navigator.pop(context),
)
],
);
});
}
@override
Widget build(BuildContext context) {
double scaleFactorWidth = 360 / MediaQuery.of(context).size.width;
double scaleFactorHeight = 592 / MediaQuery.of(context).size.height;
//=====This is the scale factor for mobiles
double scaleFactorScreenMobile = (MediaQuery.of(context).size.width
MediaQuery.of(context).size.height) /
(SonyZRWidth SonyZRHeight);
double scaleFactorTabletLandscape = scaleFactorScreenMobile - 0.5;
//==== This is to determine the shortest side of the device to determine if iPad/Tablet or mobile phone
//==== 552 was selected based on my tablet Lenovo TAB 2 A7, physical number were extracted from the App in debug mode
final double shortestSide = MediaQuery.of(context).size.shortestSide;
final bool useMobileLayout = shortestSide < 552;
//====== This to force the mobile device to be in Portrait mode only ========
//===========================================================================
if (useMobileLayout) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}
double mobilePadding() {
double valuePadding;
if (useMobileLayout == true) {
valuePadding = 20;
} else {
valuePadding = 60;
}
return valuePadding;
}
Widget buildContactUsTabletLandscape() {
return Center(
child: Stack(
children: [
Container(
height: 0.4 * MediaQuery.of(context).size.height,
width: 1 * MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
// image: DecorationImage(
// image: AssetImage('images/header.png'),
// fit: BoxFit.fill,
// ),
),
),
Center(
child: SingleChildScrollView(
child: Center(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
border: Border.all(color: kAppGrey),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 1,
blurRadius: 3,
offset:
const Offset(0, 1), // changes position of shadow
),
],
),
height: useMobileLayout
? 0.75 * MediaQuery.of(context).size.height
: 0.75 * MediaQuery.of(context).size.height,
width: 0.90 * MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.only(
left: 60, right: 60, bottom: 10.0, top: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset('images/email2.png'),
const SizedBox(width: 15),
Text(
'Contact Us',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: kAppGreyFont,
fontSize: 18.0,
),
textAlign: TextAlign.center,
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
],
),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
contactUsHeader,
style: const TextStyle(
fontSize: 12,
color: Colors.black,
wordSpacing: 1,
),
textAlign: TextAlign.left,
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
FloatingActionButton(
backgroundColor: activateSend() == true
? kAppGreen
: kAppGreen.withOpacity(0.4),
child: Transform.rotate(
angle: -30 * pi / 180,
child: const Icon(
Icons.send,
size: 35,
),
),
elevation: 8,
onPressed: () {
setState(() {
if (activateSend() == true) {
feedBackEmail();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const HomePage();
},
),
);
} else {
toastisMissing();
}
});
},
),
],
),
const SizedBox(height: 15),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Subject',
style: const TextStyle(fontSize: 12),
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
const SizedBox(height: 10),
SizedBox(
height: 50,
child: Center(
child: TextFormField(
focusNode: focusSubject,
controller: _fieldSubject,
style: TextStyle(
fontSize: 17 *
(useMobileLayout
? scaleFactorScreenMobile - 0.2
: scaleFactorTabletLandscape)),
onTap: () {},
onChanged: (_) => listenerFieldSubject(),
textAlignVertical: TextAlignVertical.bottom,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Subject',
hintText: 'Subject...',
),
),
),
),
],
),
Text(
'Content',
style: const TextStyle(fontSize: 12),
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
const SizedBox(height: 10),
TextFormField(
focusNode: focusFeedBack,
controller: _fieldFeedBack,
onTap: () {
activateSend() ? feedBackEmail() : null;
},
onChanged: (_) => listenerFieldFeedBack(),
maxLines: 3,
style: TextStyle(
fontSize: 17 *
(useMobileLayout
? scaleFactorScreenMobile - 0.2
: scaleFactorTabletLandscape)),
textAlign: TextAlign.start,
textAlignVertical: TextAlignVertical.top,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'My Message',
hintText: 'Please write here...',
),
),
const SizedBox(height: 10),
],
),
),
),
),
),
),
],
),
);
}
//====this is for mobile & tablet portrait mode
Widget buildMobilePortrait() {
return Center(
child: Stack(
children: [
Container(
height: 0.4 * MediaQuery.of(context).size.height,
width: 1 * MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
// image: DecorationImage(
// image: AssetImage('images/header.png'),
// fit: BoxFit.fill,
// ),
),
),
Center(
child: SingleChildScrollView(
child: Center(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
border: Border.all(color: kAppGrey),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 1,
blurRadius: 3,
offset:
const Offset(0, 1), // changes position of shadow
),
],
),
height: useMobileLayout
? 0.75 * MediaQuery.of(context).size.height
: 0.75 * MediaQuery.of(context).size.height,
width: 0.90 * MediaQuery.of(context).size.width,
child: Padding(
padding: EdgeInsets.only(
left: mobilePadding(),
right: mobilePadding(),
bottom: 10.0,
top: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset('images/email2.png'),
const SizedBox(width: 15),
Text(
'Contact Us',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: kAppGreyFont,
fontSize: 18.0,
),
textAlign: TextAlign.center,
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
],
),
const SizedBox(height: 15),
Text(
contactUsHeader,
style: const TextStyle(
fontSize: 12,
color: Colors.black,
wordSpacing: 1,
),
textAlign: TextAlign.left,
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
const SizedBox(height: 15),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Subject',
style: const TextStyle(fontSize: 12),
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
const SizedBox(height: 10),
SizedBox(
height: 50,
child: Center(
child: TextFormField(
focusNode: focusSubject,
controller: _fieldSubject,
style: TextStyle(
fontSize: 17 *
(useMobileLayout
? scaleFactorScreenMobile - 0.2
: scaleFactorTabletLandscape)),
onTap: () {},
onChanged: (_) => listenerFieldSubject(),
textAlignVertical: TextAlignVertical.bottom,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Subject',
hintText: 'Subject...',
),
),
),
),
],
),
const SizedBox(height: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Content',
style: const TextStyle(fontSize: 12),
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
const SizedBox(height: 10),
SizedBox(
height: 150,
child: TextFormField(
focusNode: focusFeedBack,
controller: _fieldFeedBack,
onTap: () {
activateSend() ? feedBackEmail() : null;
},
onChanged: (_) => listenerFieldFeedBack(),
maxLines: 5,
style: TextStyle(
fontSize: 17 *
(useMobileLayout
? scaleFactorScreenMobile - 0.2
: scaleFactorTabletLandscape)),
textAlign: TextAlign.start,
textAlignVertical: TextAlignVertical.top,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'My Message',
hintText: 'Please write here...',
),
),
),
],
),
const SizedBox(height: 10),
SizedBox(
height: 0.08 * MediaQuery.of(context).size.height,
width: 0.82 * MediaQuery.of(context).size.width,
child: TextButton.icon(
onPressed: () {
if (activateSend() == true) {
feedBackEmail();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const HomePage();
},
),
);
} else {
toastisMissing();
}
},
label: Text(
'Send',
style: const TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1,
),
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape 0.8,
),
icon: Icon(
Icons.email_rounded,
size: 30 *
(useMobileLayout
? scaleFactorScreenMobile - 0.2
: scaleFactorTabletLandscape),
color: Colors.white,
),
style: ButtonStyle(
elevation: MaterialStateProperty.all(5),
backgroundColor:
MaterialStateProperty.all<Color>(
activateSend() == true
? kAppGreen
: kAppGreen.withOpacity(0.4)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
// side: const BorderSide(color: Colors.black),
),
),
),
),
),
],
),
),
),
),
),
),
],
),
);
}
return Scaffold(
backgroundColor: kAppGrey,
appBar: AppBar(
backgroundColor: kAppGrey,
elevation: 0,
centerTitle: true,
iconTheme: const IconThemeData(
color: kAppGreyFont, //change your color here
),
title: Text(
'Contact Us',
style: kAppBarTitleHeader(),
textScaleFactor: useMobileLayout
? scaleFactorScreenMobile
: scaleFactorTabletLandscape,
),
),
body: SafeArea(
child: OrientationBuilder(
builder: (context, orientation) =>
orientation == Orientation.landscape
//================= This is for LandScape mode for iPad/Tablets
? buildContactUsTabletLandscape()
//================= This is for Portrait mode for iPad/Tablets
: buildMobilePortrait(),
),
),
);
}
}
also, I tried to use MediaQuery instead of OrientationBuilder
child: useMobileLayout
? buildMixingMobile()
: MediaQuery.of(context).orientation == Orientation.portrait
? buildMixingTabletPortrait()
: buildMixingTabletLandscape(),
),
I don't understand what is the reason for this problem & I can't solve it... please help
CodePudding user response:
In your release android manifest please remove this line
android:screenOrientation="portrait"
CodePudding user response:
I finally find the solution for the issue, the main cause is SystemChrome
since as per my code I wanted the mobile screen to be in the portrait mode always so I added
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}
and for some how the app started to implement the same even in the tablet landscape mode... so I made some adjustment in the App code such as
child: !useMobileLayout
? MediaQuery.of(context).orientation == Orientation.portrait
? buildMixingTabletPortrait()
: buildMixingTabletLandscape()
: buildMixingMobile(scaleFactorScreenMobile),
),
& then I added the condition to change the orientation inside the mobile mode widget as the following
Widget buildMixingMobile(double scaleFactorScreenMobile) {
//====This to make the mobile screen always in the portrait orientation
final isPortrait =
MediaQuery.of(context).orientation == Orientation.landscape;
if (isPortrait) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}
//=======================================================================
return Align(
Now the App is working as I wanted