Flutter: bagaimana cara mencegah perubahan orientasi perangkat dan memaksa potret?

124

Saya ingin mencegah aplikasi saya mengubah orientasinya dan memaksa tata letak untuk tetap menggunakan "potret".

Di main.dart, saya meletakkan:

void main(){
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]);
  runApp(new MyApp());
}

tetapi saat saya menggunakan tombol putar Simulator Android, tata letaknya "mengikuti" orientasi perangkat baru ...

Bagaimana saya bisa mengatasi ini?

Terima kasih

boeledi
sumber
4
Dengan asumsi Anda mengimpor 'package:flutter/services.dart', maka mungkin itu bug: github.com/flutter/flutter/issues/13238
Brian Kung
Tidak yakin mengapa ini terjadi pada Anda. Saya mencoba menjalankan kode Anda pada emulator dan juga perangkat saya sendiri dan berfungsi dengan baik.
Hemanth Raj
SystemChrome.setPreferredOrientationsmengembalikan secara asinkron, jadi sepertinya runAppharus diapit oleh a then.
Ken

Jawaban:

192

Impor package:flutter/services.dart, lalu

Masukkan ke SystemChrome.setPreferredOrientationsdalam Widget build()metode.

Contoh:

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitUp,
        DeviceOrientation.portraitDown,
      ]);
      return new MaterialApp(...);
    }
  }

Memperbarui

Solusi ini mungkin tidak berfungsi untuk beberapa perangkat IOS seperti yang disebutkan dalam dokumentasi flutter yang diperbarui pada Oktober 2019.

Mereka Menyarankan untuk memperbaiki orientasi dengan mengatur UISupportedInterfaceOrientations di Info.plist seperti ini

<array>
    <string>UIInterfaceOrientationPortrait</string>
</array>

Untuk informasi lebih lanjut https://github.com/flutter/flutter/issues/27235#issuecomment-508995063

Tukang batu
sumber
Bekerja. Terima Kasih <3
Suthura Sudharaka
1
Jika Anda meletakkan SystemChrome.setPreferredOrientations di main, Anda akan mendapatkan kesalahan: ServicesBinding.defaultBinaryMessenger diakses sebelum pengikatan diinisialisasi. Memasukkan kode dalam build berfungsi karena binding telah diinisialisasi pada titik ini.
Singa Emas
77

@boeledi, Jika Anda ingin "mengunci" orientasi perangkat dan tidak mengizinkannya untuk berubah saat pengguna memutar ponselnya, ini mudah diatur seperti di bawah ini,

// This did not work as requirement
void main() {
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  runApp(new MyApp());
}

Anda harus menunggu hingga setPreferredOrientationsselesai dan kemudian memulai aplikasi

// This will works always for lock screen Orientation.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
    .then((_) {
      runApp(new MyApp());
    });
}
TejaDroid
sumber
Terkadang terjadi kesalahan saat mengompilasi, Anda harus menggunakan solusi asli. Menambahkan 'android: screenOrientation = "portrait"' ke MainActivity di AndroidManifest seperti saran Abeer Iqbal berhasil untuk saya di Android.
Tincho825
44

iOS:

Menelepon SystemChrome.setPreferredOrientations()tidak berfungsi untuk saya, dan saya harus mengubah Device Orientationdalam proyek Xcode sebagai berikut:

masukkan deskripsi gambar di sini

Android:

Setel screenOrientationatribut ke portraituntuk aktivitas utama dalam file android/app/src/main/AndroidManifest.xmlsebagai berikut:

masukkan deskripsi gambar di sini

Hejazi
sumber
Saya memiliki masalah yang sama, apakah Anda menjalankannya di iPad? Saya hanya menguji di iPad dan ini tampaknya menjadi masalah: github.com/flutter/flutter/issues/27235
Anak Laki
android: Atribut ini ditambahkan di API level 24.
BloodLoss
Saya gunakan screenOrientationsejak API level 8 untuk Android. @BloodLoss, saya pikir Anda membacanya di dokumen, tetapi tentang resizeableActivityatribut. Periksa kembali tautannya. ^^
Erick M. Sprengel
22

Metode 'setPreferredOrientations' mengembalikan objek Future. Berdasarkan dokumentasi, Future mewakili beberapa nilai yang akan tersedia di suatu tempat di masa mendatang. Itulah mengapa Anda harus menunggu sampai tersedia dan kemudian melanjutkan dengan aplikasi. Oleh karena itu, harus digunakan metode 'then', yang, sesuai definisi, "mendaftarkan panggilan balik yang akan dipanggil saat Future selesai". Karenanya, Anda harus menggunakan kode ini:

  void main() {
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) {
      runApp(new App());
    });
   }

Selain itu, file berikut harus diimpor:

'paket: flutter / services.dart'

Ara Mkrtchyan
sumber
Saya dapat mengonfirmasi bahwa ini berfungsi. Tapi gunakan whenComplete () daripada then (), ketika fungsi tersebut tidak mendapatkan param.
Csaba Gergely
20

Buka android / app / src / main / AndroidManifest.xml dan tambahkan baris berikut di MainActivity:

android:screenOrientation="portrait"

Jika Anda memiliki ini:

<activity
        android:name=".MainActivity"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">

Anda akan mendapatkan hasil seperti ini:

<activity
        android:name=".MainActivity"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize">

Ini berfungsi untuk Android. Di iOS, Anda harus mengubahnya dari halaman Xcode: https://i.stack.imgur.com/hswoe.png (seperti yang dikatakan Hejazi)

Abeer Iqbal
sumber
terima kasih, INGAT urutan "potret" setelah "orientasi" configChanges itu penting.
MR_AMDEV
13

Pertama-tama impor ini di file main.dart

import 'package:flutter/services.dart';

Maka jangan copy paste lebih baik lihat (ingat) dan tulis kode di bawah ini di file main.dart

Untuk memaksa dalam mode potret :

void main() {
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp,DeviceOrientation.portraitDown])
      .then((_) => runApp(MyApp()),
  );

Untuk memaksa dalam mode lanskap :

   void main() {
      SystemChrome.setPreferredOrientations(
          [DeviceOrientation.landscapeLeft,DeviceOrientation.landscapeRight])
          .then((_) => runApp(MyApp()),
      );
Pinkesh Darji
sumber
1
Terima kasih telah mengingatkan orang untuk tidak menyalin-tempel secara membabi buta
Ryan
1
Saya mengerti mengapa Anda meminta untuk TIDAK menyalin tempel ... akhiran} hilang ... Saya menyalin tempel ... :)
rohan koshti
tidak berfungsi untuk flutter chrome
Golden Lion
13

Letakkan WidgetsFlutterBinding.ensureInitialized () jika tidak, Anda akan mendapatkan kesalahan saat membangun.

import 'package:flutter/services.dart';

    void main() async => {
          WidgetsFlutterBinding.ensureInitialized(),

          await SystemChrome.setPreferredOrientations(
              [DeviceOrientation.portraitUp]), // To turn off landscape mode

          runApp(MainApp())
        };
Berlari
sumber
5

setPreferredOrientationmengembalikan a Future<void>, jadi asynchronous. Pendekatan yang paling mudah dibaca adalah dengan mendefinisikan mainasinkron:

Future<void> main() async {
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  return runApp(new MyApp());
}
Rob Lyndon
sumber
3
Saya sangat tidak setuju. awaitadalah pola pemrograman di mana-mana yang hadir dalam berbagai bahasa, dan sangat jelas apa yang ekspresif. thenmenciptakan tingkat bersarang. Jika Anda memiliki tiga atau empat lanjutan, thenmulai menjadi sangat sulit untuk dibaca.
Rob Lyndon
.thendapat dirantai alih-alih bersarang, seperti yang diharapkan a FutureOr. Ini memungkinkan saya menggunakan pendekatan yang lebih fungsional, yang lebih mudah dibaca dan elegan. Misalnya, saya bisa menggunakan badan ekspresi alih-alih tubuh dalam kurung dengan merangkai "lalu".
Mateus Felipe
Terkadang terjadi kesalahan saat mengompilasi, Anda harus menggunakan solusi asli. Menambahkan 'android: screenOrientation = "portrait"' ke MainActivity di AndroidManifest seperti saran Abeer Iqbal berhasil untuk saya di Android.
Tincho825
Jika Anda menghadapi kesalahan: "Unhandled Exception: ServicesBinding.defaultBinaryMessenger telah diakses sebelum pengikatan diinisialisasi." coba gunakan perbaikan ini: stackoverflow.com/questions/57689492/…
Fillipe Silva
1

Pada versi flutter baru bersama dengan pengaturan preferred Orientationkita perlu menambahkan satu baris tambahan yaitu

 WidgetsFlutterBinding.ensureInitialized();

Jadi kode kerja untuk ini adalah -

import 'package:flutter/services.dart';
    void main() {
          WidgetsFlutterBinding.ensureInitialized();
          SystemChrome.setPreferredOrientations([
            DeviceOrientation.portraitUp,
            DeviceOrientation.portraitDown
          ]);
          runApp(MyApp());
        }
B.shruti
sumber
1

Di bawah ini adalah contoh resmi dari tim flutter. https://github.com/flutter/samples/blob/master/veggieseasons/lib/main.dart

import 'package:flutter/services.dart' show DeviceOrientation, SystemChrome;

void main() {
    WidgetsFlutterBinding.ensureInitialized();
    SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitUp,
        DeviceOrientation.portraitDown,
    ]);
    runApp(HomeScreen());
}
Lucas Martins Soares
sumber
0

Mencoba

 void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await SystemChrome.setPreferredOrientations(
          [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); 
    
      runApp(MyApp());
 }

Anda juga dapat mengubah pengaturan orientasi layar di manifes android dan file ios info.plist.

Bukunmi
sumber
0

Impor impor 'paket: flutter / services.dart';

Kemudian Anda menyertakan baris kode di bawah ini dalam file main.dart Anda, dan dalam metode utama Anda seperti ini:

WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitDown,
    DeviceOrientation.portraitUp,
  ]);

runApp(myApp());
Silas Ogar
sumber
-4

Solusi terbaik adalah menggunakannya dalam metode build MyApp ().

Aashar Wahla
sumber