Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Landscape mode and responsive framework #38

Closed
prateekmedia opened this issue Jan 20, 2021 · 49 comments
Closed

Landscape mode and responsive framework #38

prateekmedia opened this issue Jan 20, 2021 · 49 comments

Comments

@prateekmedia
Copy link

prateekmedia commented Jan 20, 2021

Intro

This framework works flawlessly for small screen devices, but when you turn your device into landscape mode the situation also becomes upside down.

The Problem

Although this is able to hand my approximately 450x850 mobile, but when I turn it in landscape mode then all the ui elements are too big and some are even overflowing cause of the less dpi in small screen but that's not the case in portrait mode.

You can also try this on the recreated flutter website, when you turn your phone with any resolution into landscape mode then everything becomes too big to handle event the bottomNavigationBar also doesnt respect the small screen.

It seems like it doesn't respect nor recognize small screens in landscape mode cause it thinks that the width is higher so that is true in landscape but it should also consider that the height is low in landscape mode cause the resolution becomes 850x450(in my small screen case)

Suggestion / Possible Solution

Give us the option to specify other properties for landscape mode or by default respect landscape mode cause even if the width is high in it but the height is very low in that mode, or it should understand landscape mode by itself by checking the aspect ratio which is my case is approx 2:1 in landscape mode.

Enough Talk, Show me your code

This is the code of my builder inside MaterialApp

builder: (context, widget) => ResponsiveWrapper.builder(
  BouncingScrollWrapper.builder(context, widget),
  minWidth: 450,
  defaultScale: true,
  breakpoints: [
    ResponsiveBreakpoint.resize(500, name: MOBILE),
    ResponsiveBreakpoint.autoScale(800, name: TABLET),
    ResponsiveBreakpoint.autoScale(1000, name: TABLET),
    ResponsiveBreakpoint.resize(1200, name: DESKTOP),
    ResponsiveBreakpoint.autoScale(2460, name: "4K"),
  ],
),
@rayliverified
Copy link
Contributor

Great issue. Thanks for providing a good explanation. I think I understand what you're saying but if you could provide some images of layouts that don't look right in landscape mode, that'd be great.

Thanks for using this library!

@prateekmedia
Copy link
Author

Great issue. Thanks for providing a good explanation. I think I understand what you're saying but if you could provide some images of layouts that don't look right in landscape mode, that'd be great.

Thanks for using this library!

Ok let me capture the issue

@prateekmedia
Copy link
Author

prateekmedia commented Jan 24, 2021

@searchy2

Portrait vs Landscape
Girl in a jacket

Although it fits in landscape in my other 1280x720 mobile and other tablet but the 450x850 mobile doesn't fits it well.

@rayliverified
Copy link
Contributor

Thanks, I will take a look and add a landscape param most likely.

For now, can you take a look at ResponsiveRowColumn to see if it suits your needs?

@prateekmedia

This comment has been minimized.

@rayliverified
Copy link
Contributor

Will create a fix for this issue soon.

@rayliverified
Copy link
Contributor

rayliverified commented Mar 3, 2021

Good news! MediaQuery contains the landscape and portrait orientation property.

MediaQuery.of(context).orientation
https://api.flutter.dev/flutter/widgets/MediaQueryData/orientation.html

The ResponsiveFramework resolves the correct values to MediaQuery so you can confidently use that property.

@prateekmedia
Copy link
Author

Good news! MediaQuery contains the landscape and portrait orientation property.

MediaQuery.of(context).orientation
https://api.flutter.dev/flutter/widgets/MediaQueryData/orientation.html

The ResponsiveFramework resolves the correct values to MediaQuery so you can confidently use that property.

Can you elaborate more?

@rayliverified
Copy link
Contributor

If you use MediaQueryData's orientation property, you will get Orientation.landscape and Orientation.portrait which is what you wanted right?

@prateekmedia
Copy link
Author

Hey @searchy2,

Sorry for late reply, that's not what I wanted.

If you read my problem again then it when I set the breakpoints of responsive framework then it treats like 450x850(widthxheight) in portrait but in landscape it will become 850x450 so the breakpoints will think its a Tablet and will not apply the responsive breakpoint formula (hence some of my objects will come out of the screen as I reported in start of this issue), Code reference below

builder: (context, widget) => ResponsiveWrapper.builder(
  ...
  breakpoints: [
    ResponsiveBreakpoint.resize(500, name: MOBILE),  // my 450x850 mobile will behave as a mobile in portrait
    ResponsiveBreakpoint.autoScale(800, name: TABLET), // same 450x850 mobile will behave as a tablet \
        in landscape as in this mode width and height are switched(850x450),
    ...
  ],
),

I hope you can understand the underlying issue, It is not doing what it should do i.e. become responsive on all form factors and orientations.

Regards Prateek.

@rayliverified
Copy link
Contributor

rayliverified commented Mar 14, 2021

My apologies, I thought I reopened this issue already. Thank you for the additional information.

@fdarsot
Copy link

fdarsot commented Mar 18, 2021

@searchy2
I also have the same issue. when turning my devices into landscape mode, the responsiveness is not working (everything is not fitting the screen properly). Any idea when a fix will be out?

@rayliverified
Copy link
Contributor

This'll be the next thing I look at.

@HasanMuslemani
Copy link

@searchy2 Any timeline for the fix?

@rayliverified
Copy link
Contributor

Not at the current time. This is an involved issue that needs quite a bit of thought to fix.

Do you have any suggestions?

@HasanMuslemani
Copy link

@searchy2 Are you using MediaQuery.of(context).size.width to determine the width? If so, you could change that to MediaQuery.of(context).size.shortestSide which will ensure the width is never changing even if they switch to landscape.

@rayliverified
Copy link
Contributor

I am not. That's a good suggestion, thank you!

@fdarsot
Copy link

fdarsot commented Mar 29, 2021

Any timeline for a fix @searchy2 ?

@fdarsot
Copy link

fdarsot commented Apr 13, 2021

? @searchy2

@marchellodev
Copy link

Having the exactly the same issue

builder: (context, widget) => ResponsiveWrapper.builder(
  BouncingScrollWrapper.builder(context, widget),
  minWidth: 450,
  defaultScale: true,
  breakpoints: [
    ResponsiveBreakpoint.resize(500, name: MOBILE),
    ResponsiveBreakpoint.autoScale(800, name: TABLET),
    ResponsiveBreakpoint.autoScale(1000, name: TABLET),
    ResponsiveBreakpoint.resize(1200, name: DESKTOP),
    ResponsiveBreakpoint.autoScale(2460, name: "4K"),
  ],
),

image

image

@marchellodev
Copy link

Seems to be related to #48

@marchellodev
Copy link

This is the temporary solution that seems to be working:

      builder: (context, child) {

        const portraitBrakepoints = [
          ResponsiveBreakpoint.resize(480, name: MOBILE),
          ResponsiveBreakpoint.resize(520, name: MOBILE, scaleFactor: 1.4),
          ResponsiveBreakpoint.resize(600, name: TABLET, scaleFactor: 1.2),
          ResponsiveBreakpoint.autoScale(800, name: TABLET, scaleFactor: 1.4),
          ResponsiveBreakpoint.resize(1000, name: DESKTOP, scaleFactor: 1.8),
          ResponsiveBreakpoint.autoScale(2460, name: '4K', scaleFactor: 2.2),
        ];

        const landscapeBrakepoints = [
          ResponsiveBreakpoint.resize(480, name: MOBILE, scaleFactor: 0.6),
          ResponsiveBreakpoint.resize(520, name: MOBILE, scaleFactor: 0.6),
          ResponsiveBreakpoint.resize(600, name: TABLET, scaleFactor: 0.8),
          ResponsiveBreakpoint.autoScale(800, name: TABLET, scaleFactor: 0.8),
          ResponsiveBreakpoint.resize(1000, name: DESKTOP, scaleFactor: 1.1),
          ResponsiveBreakpoint.autoScale(1200, name: DESKTOP, scaleFactor: 1.1),
          ResponsiveBreakpoint.autoScale(2460, name: '4K', scaleFactor: 1.7),
        ];

        return Container(
          key: UniqueKey(),
          child: ResponsiveWrapper.builder(
              child: child!,
              minWidth: 480,
              defaultScale: true,
              breakpoints:
                  MediaQuery.of(context).orientation == Orientation.portrait
                      ? portraitBrakepoints
                      : landscapeBrakepoints),
        );
      },

key: UniqueKey() causes the app to restart when the screen size changes. Without the key it does not seeem to be working at all.

@searchy2 Can you make it so we can specify different breakpoints for different opientations please :> ?
i. e.

ResponsiveWrapper(
    child,
    breakpoints: [],
    breakpointsLandscape: [],
)

Although in this case the desktop app does not behave consistently when resizing window, since orientation seems to be calculated based on height and width.
So I would suggest to ignore the orientation variable on desktop and add third array with breakpoints :)

why is responsiveness so complicated...

@rayliverified
Copy link
Contributor

Thank you for the experiments and additional information.
I think I have the info I need to create a solution.

I can probably release a new version this week if everyone in this thread is willing to help me test.

@fdarsot
Copy link

fdarsot commented May 10, 2021

@searchy2 sure! eagerly awaiting the release!

@fdarsot
Copy link

fdarsot commented May 17, 2021

@searchy2 any luck?

@fdarsot
Copy link

fdarsot commented May 27, 2021

@searchy2 ??

@marchellodev
Copy link

@searchy2 If you don't have the time to fix this, could you please tell us what is the proper way to do it, so that we can submit a PR?

@fdarsot
Copy link

fdarsot commented Jun 3, 2021

@searchy2 my team and i are getting close to launch and this is one of the few missing pieces. please update when you can.

@rayliverified
Copy link
Contributor

My apologies, the solution here is to add a landscape breakpoints param and switch based on the media query returned orientation value.

I don't have time today but I'll try this weekend.

@rayliverified
Copy link
Contributor

Good news, I've added support for landscape breakpoints with the v0.1.1 release!

Landscape mode support was as extensive as I imagined and really needed a good think through.
The crux of the issue is that Flutter has no REAL landscape mode detection. The orientation is virtually computed based on if width > height. This means that landscape mode makes no sense on desktop or web. By default, the ResponsiveFramework only applies landscape breakpoints on iOS, Android, and Fuchsia. However, to keep things customizable, the supported landscape platforms can be customized by passing a list of supported platforms to landscapePlatforms.

Please test and let me know your thoughts and suggestions.

This is not full landscape support as it is missing minWidthLandscape, maxWidthLandscape, defaultScaleLandscape, defaultScaleFactorLandscape, etc. Any help adding support for those features is appreciated!

@fdarsot
Copy link

fdarsot commented Jun 9, 2021

i think the issue still exists? i entered the following

landscapePlatforms: [
TargetPlatform.android,
TargetPlatform.iOS,
],
landscapeBreakpoints: [
ResponsiveBreakpoint.autoScaleDown(450,
name: MOBILE, scaleFactor: 0.73),
ResponsiveBreakpoint.autoScaleDown(800,
name: TABLET, scaleFactor: 0.73),
ResponsiveBreakpoint.autoScaleDown(1000,
name: TABLET, scaleFactor: 0.73),
ResponsiveBreakpoint.autoScaleDown(1200,
name: DESKTOP, scaleFactor: 0.73),
ResponsiveBreakpoint.autoScaleDown(2460,
name: "4K", scaleFactor: 0.73),
],

and it's still not working when i switch from portrait to landscape

anyone else?
@searchy2

@HasanMuslemani
Copy link

@fdarsot I could be wrong here but wouldn't the width change when in landscape so I don't think it'd be the same breakpoint numbers as portrait.

@fdarsot
Copy link

fdarsot commented Jun 9, 2021

ohhh good point. i think you are correct @HasanMuslemani i was going based on the example in the repo. let me try new breakpoints

@fdarsot
Copy link

fdarsot commented Jun 9, 2021

tried with different breakpoints, it still isnt working

@fdarsot
Copy link

fdarsot commented Jun 9, 2021

is it working for anyone else?

@prateekmedia
Copy link
Author

is it working for anyone else?

What are your new breakpoints?

@fdarsot
Copy link

fdarsot commented Jun 9, 2021

@prateekmedia i checked what my screen width was when it was in landscape mode and adjusted it to that.

landscapePlatforms: [
TargetPlatform.android,
TargetPlatform.iOS,
],
landscapeBreakpoints: [
ResponsiveBreakpoint.autoScaleDown(640,
name: MOBILE, scaleFactor: 0.73)
],

@rayliverified
Copy link
Contributor

Hmmm.. I'll find out the issue with some tests.

For now, you need to test on a target device in order to have landscape apply.

Landscape mode isn't enabled by default on Web or Desktop.
You CAN enable it by adding windows, web, or macOS into the landscapePlatforms.

@fdarsot
Copy link

fdarsot commented Jun 9, 2021

@searchy2 im testing on a real device with targeted breakpoints

im only developing for Android and IOS btw

@rayliverified
Copy link
Contributor

Well, that's unfortunate.

I'll take a look tomorrow, the bulk of the work is done so it's probably a quick fix.

And can add some tests!

@fdarsot
Copy link

fdarsot commented Jun 9, 2021

Thank you for all your work btw! i think we're close. this is one of the few last things needed before we launch and it would be great to have.

@marchellodev
Copy link

I believe the problem is that flutter does not trigger MaterialApp.builder when orientation changes

@rayliverified
Copy link
Contributor

@fdarsot @prateekmedia
v0.1.2 Released!

  • Full support for landscapeBreakpoints - breakpoints in landscape mode. Create landscape overrides with minWidthLandscape, maxWidthLandscape, defaultScaleLandscape, etc.
  • Use ResponsiveTargetPlatform to enable landscape support for platforms including web.

I've verified through tests that landscape mode now works correctly.
Please note that landscape can be VERY confusing, especially when testing on desktop or web.

To test on desktop or web:

  1. Add ResponsiveTargetPlatform.windows or the test platform to landscapePlatforms
  2. Add landscape breakpoints to breakpointsLandscape.
  3. Shrink the window height to something small like 200px. If the height is too large such as 600px, any width smaller than 600px activates portrait mode instead of landscape.
  4. Check the maxWidth, minWidth, etc settings. You must override them with maxWidthLandscape if you want to use different values in landscape mode. Otherwise, the values default to the portrait values.

Please test and hopefully everyone's issues are resolved.

@rayliverified
Copy link
Contributor

In spite of the seemingly complex concepts here, landscape and portrait breakpoints switch seemlessly and it's a beauty to behold.

@prateekmedia
Copy link
Author

In spite of the seemingly complex concepts here, landscape and portrait breakpoints switch seemlessly and it's a beauty to behold.

Ok looks great, although I will test it when I'm free. If anyone has any query then I will reopen it.

@elvosparsley
Copy link

I can't get this to work.
Has anybody got a working project that I can test with?
Even modifying the tutorial sample doesn't work.
Any help would be gratefully received.

@prateekmedia prateekmedia reopened this Apr 4, 2022
@marchellodev
Copy link

@elvosparsley You need to specify different breakpoints for both breakpoints and breakpointsLandscape.

Here's how I am doing it in my app: https://github.com/marchellodev/sharik/blob/master/lib/main.dart#L63

@prateekmedia
Copy link
Author

Closing again as issue is answered.

@elvosparsley
Copy link

@elvosparsley You need to specify different breakpoints for both breakpoints and breakpointsLandscape.

Here's how I am doing it in my app: https://github.com/marchellodev/sharik/blob/master/lib/main.dart#L63

Many thanks for the example, I was missing the scaleFactor in the breakpoints, works great now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants