Jangan memuat ulang aplikasi ketika orientasi berubah

152

Saya tidak perlu mengubah apa pun saat layar diputar. Aplikasi saya menampilkan gambar acak ketika pertama kali memuat dan memutar perangkat tidak boleh memilih gambar acak lain. Bagaimana saya dapat (secara sederhana) menghentikan perilaku ini?

Jimmy D
sumber
1
Dimungkinkan juga untuk mengunci (dan mungkin membuka kunci) orientasi layar dari kode. Panggil saja Screen.lockOrientation(this)dari github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/… untuk ini. Ini memungkinkan membuka kunci yang manifes tidak.
gak
@Escobar Ceaser Apa solusi yang tepat untuk pertanyaan ini. Bahkan saya memiliki persyaratan yang sama.
Prab
Saya ingin melakukan ini dalam kode program.
pollaris

Jawaban:

249

Secara umum ada tiga cara untuk melakukan ini:

  1. Seperti yang disarankan beberapa jawaban, Anda dapat membedakan kasus aktivitas yang dibuat untuk pertama kalinya dan dipulihkan savedInstanceState. Ini dilakukan dengan onSaveInstanceStatemengganti dan memeriksa parameter onCreate.

  2. Anda dapat mengunci aktivitas dalam satu orientasi dengan menambahkan android:screenOrientation="portrait"(atau "landscape") ke <activity>dalam manifes Anda.

  3. Anda bisa mengatakan sistem yang dimaksudkan untuk menangani perubahan layar untuk diri sendiri dengan menentukan android:configChanges="orientation|screenSize"di <activity>tag. Dengan cara ini aktivitas tidak akan dibuat ulang, tetapi akan menerima panggilan balik (yang dapat Anda abaikan karena tidak berguna untuk Anda).

Secara pribadi saya akan pergi dengan (3). Tentu saja jika mengunci aplikasi ke salah satu orientasi baik-baik saja dengan Anda, Anda juga dapat pergi dengan (2).

Xion
sumber
13
Jadi untuk # 3 yang Anda katakan yang harus saya lakukan adalah menambahkan baris ke manifes saya? Karena itu tidak berhasil.
Jimmy D
2
# 3 Silakan periksa stackoverflow.com/questions/456211/…
Yeo
16
@EscobarCeaser, Untuk Android 3.2 dan di atasnya, Anda perluandroid:configChanges="orientation|screenSize"
Pacerier
9
android:configChanges="orientation|screenSize"bekerja untukku. Terima kasih @Pacerier
Don
1
tolong, perbarui kasus jawaban Anda # 3 dengan android:configChanges="orientation|screenSize" nilai untuk API> = 13, karena banyak orang melihat jawaban Anda sebagai yang utama!
radistao
215

Jawaban Xion sudah dekat, tetapi # 3 ( android:configChanes="orientation") tidak akan berfungsi kecuali aplikasi memiliki tingkat API 12 atau lebih rendah.

Di API level 13 atau lebih, ukuran layar berubah ketika orientasi berubah, jadi ini masih menyebabkan aktivitas dihancurkan dan dimulai ketika orientasi berubah.

Cukup tambahkan atribut "screenSize" seperti yang saya lakukan di bawah ini:

<activity
    android:name=".YourActivityName"
    android:configChanges="orientation|screenSize">
</activity>

Sekarang, ketika Anda mengubah orientasi (dan ukuran layar berubah), aktivitas mempertahankan statusnya dan onConfigurationChanged()dipanggil. Ini akan menjaga apa pun yang ada di layar (yaitu: halaman web di tampilan Web) ketika orientasi berubah.

Pelajari ini dari situs ini: http://developer.android.com/guide/topics/manifest/activity-element.html

Juga, ini tampaknya praktik yang buruk jadi baca tautan di bawah ini tentang Menangani Perubahan Waktu Runtime:

http://developer.android.com/guide/topics/resources/runtime-changes.html

corbin
sumber
2
Terima kasih ... kerjanya setelah menambahkan "screenSize" dengan "orientasi"
Pratik Butani
Bekerja di Samsung Galaxy Nexus android 4.2.1! android:configChanges="orientation|screenSize"
Vincent Ducastel
Luar biasa. Telah bekerja melalui kode selama berjam-jam untuk menyelesaikan masalah yang saya miliki dengan memuat ulang aktivitas dan video mulai dari awal. Dan inilah solusinya! ++++ 1
Mathias Asberg
6
Latihan yang buruk? Pfft, orang-orang kehidupan nyata memiliki tenggat waktu dan jika itu berhasil, itu akan berhasil;)
Kacy
Jika ini adalah praktik yang buruk lalu mengapa itu mendapatkan begitu banyak upvotes ??
Sharp Edge
26

Anda hanya perlu pergi ke bagian AndroidManifest.xmldalam dan di dalam label aktivitas Anda, Anda harus mengetikkan baris kode ini sebagai seseorang di sana berkata:

android:configChanges="orientation|screenSize"

Jadi, Anda akan memiliki sesuatu seperti ini:

<activity android:name="ActivityMenu"
android:configChanges="orientation|screenSize">
</activity>

Semoga berhasil!

Josue Rocha
sumber
itu tidak memuat tata letak-tata letak tanah saya. :( tidak bekerja untuk saya
piyush poriya
16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>

Cukup tambahkan android:configChanges="orientation|screenSize" di tab aktivitas file manifes.

Jadi, Aktivitas tidak akan dimulai kembali ketika orientasi berubah.

Aiyaz Parmar
sumber
Bekerja. Tetapi ketika saya menggunakan tata letak terpisah untuk setiap orientasi layout.xml dan tata letak-land.xml. penerapan tata letak lansekap untuk kedua orientasi. Jika saya menggunakan "orientasi" saja, ini memberikan apa yang saya harapkan tetapi memuat ulang. Bisakah Anda membantu dalam hal ini?
Karthikeyan Ve
1
@KarthikeyanVe Itulah masalahnya ketika Anda mencoba menipu. Anda harus memulai kembali aktivitas Anda untuk mengubah tata letak. Silakan dan gunakan saja solusi nyata, yaitu menggunakan onSaveInstanceState()dan onCreate().
Marc Plano-Lesay
@ MarcPlano-Lesay dan bagaimana saya bisa melakukan itu?
Ahsan
@ Weaboo solusi aktual terkait dengan pertanyaan: developer.android.com/guide/topics/resources/…
Marc Plano-Lesay
@ MarcPlano-Lesay Saya sudah memisahkan tata letak untuk mode potret dan lansekap, jika saya membuka aplikasi dalam mode lansekap atau potret, itu berfungsi dengan baik, tetapi setiap kali saya mencoba mengubah orientasi saat dijalankan, aplikasi akan tertutup, namun ketika saya masuk ke aplikasi saya dan kemudian navigasikan ke MainActivity dan cobalah untuk mengubah orientasi itu memuat ulang kegiatan itu dan berfungsi dengan baik. Sekarang pertanyaannya adalah mengapa? Apakah ada kesalahan logis dalam kode saya? Idk, tapi saya sudah mencoba men-debug aplikasi beberapa kali, dan saya tidak dapat menemukan apa pun. Selain itu saya tidak ingin memulai kembali aktivitas saya, mengapa kita tidak bisa menyesuaikan tata letak masing-masing setiap kali konfigurasi berubah?
Ahsan
10

Ini pengalaman saya bahwa sebenarnya lebih baik hanya berurusan dengan perubahan orientasi dengan benar daripada mencoba untuk menunjukkan perilaku yang tidak standar.

Anda harus menyimpan gambar yang sedang ditampilkan onSaveInstanceState()dan mengembalikannya dengan benar ketika aplikasi Anda berjalan onCreate()lagi.

dmon
sumber
# 3 adalah solusi yang sangat valid. Ini alat yang tepat dibuat untuk memecahkan masalah yang tepat ini. Mengapa Anda mengatakan bahwa ini menyemir?
Pacerier
1
@Pacerier Baru saja membaca dokumen. "Catatan: Penggunaan android:configChangesharus dihindari dan digunakan hanya sebagai pilihan terakhir. Harap baca Menangani Perubahan Waktu Runtime untuk informasi lebih lanjut tentang cara menangani restart dengan benar karena perubahan konfigurasi."
Marc Plano-Lesay
Bisakah Anda memposting contoh menyimpan dan memulihkan.
pollaris
6

Solusi ini sejauh ini merupakan solusi terbaik. Dalam file manifes Anda tambahkan

<activity
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:name="your activity name"
    android:label="@string/app_name" 
    android:screenOrientation="landscape">
  </activity

Dan di kelas aktivitas Anda tambahkan kode berikut

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //your code
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
  //your code

    }
}
A Raj
sumber
4

tambahkan android:configChanges="keyboardHidden|orientation|screenSize"untuk semua tag aktivitas aplikasi dalam manifes.

Oubaida AlQuraan
sumber
3

Tambahkan saja ini ke AndroidManifest.xml

<activity android:screenOrientation="landscape">

Maksud saya, ada tag aktivitas, tambahkan ini sebagai parameter lain. Jika Anda membutuhkan orientasi potret, ubah lanskap menjadi potret. Semoga ini membantu.

Egor
sumber
Saya tidak ingin menghilangkan kemampuan untuk memutar layar. saya hanya tidak ingin aplikasi saya dimuat ulang ... seperti yang saya sebutkan.
Jimmy D
ps ... ini tidak berhasil. itu hanya memaksa aplikasi untuk ditampilkan dalam orientasi tertentu. memutar layar masih memuat ulang aktivitas
Jimmy D
3

Dalam file manifiest tambahkan ke setiap aktivitas ini. Ini akan membantu

android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"
Jevgenij Kononov
sumber
screenLayout bekerja untuk saya, mencegah penyegaran ketika mengubah ukuran aplikasi untuk splitscreen di android
Terren
2

Semua jawaban di atas tidak berfungsi untuk saya. Jadi, saya telah tetap dengan menyebutkan labeldengan screenOrientationseperti di bawah ini. Sekarang semuanya baik-baik saja

<activity android:name=".activity.VideoWebViewActivity"
        android:label="@string/app_name"
        android:configChanges="orientation|screenSize"/>
Bahu
sumber
1

Simpan detail gambar di Anda onPause()atau onStop()dan gunakan di onCreate(Bundle savedInstanceState)untuk memulihkan gambar.

EDIT:

Info lebih lanjut tentang proses sebenarnya dirinci di sini http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle karena berbeda di Honeycomb daripada versi Android sebelumnya.

layanan teknis
sumber
sebenarnya Anda harus melakukannya dalam metode onSaveInstanceState ()
Willi Mentzel
1

cukup gunakan: android:configChanges="keyboardHidden|orientation"

Masoud Banimahd
sumber
1

Seperti yang disebutkan Pacerier,

android:configChanges="orientation|screenSize"

Don Larynx
sumber
-1

Saya tidak tahu apakah solusi yang terbaik, tetapi saya jelaskan di sini:

Pertama-tama, Anda perlu sertifikat dengan kelas Anda. Aplikasi aplikasi Anda ada dalam manifes ini:

<application
    android:name=".App"
    ...

Kedua, di App kelas saya saya suka ini:

public class App extends Application {
    public static boolean isOrientationChanged = false;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(@NotNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ||
                newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            isOrientationChanged = true;
        }
    }

}

Ketiga, Anda perlu mengatur bendera ke Perubahan Orientasi, dalam kasus saya, saya selalu mengaturnya ketika aktivitas sebelumnya dalam navigasi aplikasi dipanggil, jadi hanya memanggil satu kali ketika aktivitas nanti dibuat.

isOrientationChanged = false;

Jadi setiap kali saya mengubah orientasi layar saya dalam konteks itu, saya mengaturnya setiap kali mengubah pengaturan ini, memeriksa apakah ada perubahan orientasi, jika demikian, itu memvalidasi berdasarkan nilai dari bendera itu.

Pada dasarnya, saya harus menggunakannya setiap kali saya membuat permintaan retrofit asinkron, yang disebutnya setiap saat yang mengubah orientasi, terus-menerus menabrak aplikasi:

if (!isOrientationChanged) {
    presenter.retrieveAddress(this, idClient, TYPE_ADDRESS);
}

Saya tidak tahu apakah itu solusi yang paling elegan dan indah, tapi setidaknya ini fungsional :)

michel566
sumber
-2

Tambahkan kode ini setelah onCreatemetode, dalam aktivitas Anda yang berisiWebView

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);    
}

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}
Amir Aslam
sumber
1
Bagaimana cara kerjanya? Bukankah Anda hanya mengatakan sesuatu secara eksplisit ke runtime, apa yang seharusnya dilakukan secara default?
Danielson