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


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


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());
    });
}

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


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'


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)


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()),
      );

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())
        };

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());
}

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());
        }


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.


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());

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.