Rotate Widget When Orientation Changes in Flutter (But Keeping The Layout Position)

Issue

I am creating a camera app which naturally needs to support both Portrait and Landscape orientation.

Is it possible to rotate the widgets without changing the widget layout position? (They are still in place, but the icons are rotated according to the current orientation, just like a regular camera app behaviour)

Any ideas please?

PORTRAIT
PORTRAIT LAYOUT

LANDSCAPE
LANDSCAPE LAYOUT

LANDSCAPE
LANDSCAPE LAYOUT EXPLANATION

Solution

Unfortunately flutter doesn’t detect orientation side like portrait up or portrait down

so we will need a package to help to achieve this behaviour native_device_orientation

1- you need to lock screen orientation to portraitUp
2- now we should depend on the sensor data to get the device correct orientation without rotating the app. native_device_orientation will help us achieve that
3- using RotatedBox or Transform.rotate to react to current screen orientation as you like

Complete working example

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:native_device_orientation/native_device_orientation.dart';

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); // -->[1]
  runApp(const App());
}

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: NativeDeviceOrientationReader(
          useSensor: true, // --> [2]
          builder: (ctx) {
            final orientation = NativeDeviceOrientationReader.orientation(ctx);
            int turns = 0;
            switch (orientation) {
              case NativeDeviceOrientation.portraitUp:
                turns = 0;
                break;
              case NativeDeviceOrientation.portraitDown:
                turns = 2;
                break;
              case NativeDeviceOrientation.landscapeLeft:
                turns = 1;
                break;
              case NativeDeviceOrientation.landscapeRight:
                turns = 3;
                break;
              case NativeDeviceOrientation.unknown:
                turns = 0;
                break;
            }
            // --> [3]
            return RotatedBox( 
              quarterTurns: turns,
              child: const Icon(
                Icons.abc,
                size: 100,
              ),
            );
          },
        ),
      ),
    );
  }
}

Answered By – Hosam Hasan

Answer Checked By – Mary Flores (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *