Cara mengunci orientasi selama runtime

107

Apakah ada cara untuk mengunci orientasi selama runtime? Misalnya, saya ingin mengizinkan pengguna mengunci layar ke lanskap jika pengguna saat ini dalam lanskap dan mengaktifkan opsi menu.

Jared
sumber

Jawaban:

133
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Memanggil suatu aktivitas, akan menguncinya ke lanskap. Cari tanda lain di kelas ActivityInfo. Anda dapat menguncinya kembali ke potret atau membuatnya digerakkan oleh sensor / slider.

Info lebih lanjut di sini: http://www.devx.com/wireless/Article/40792

haseman
sumber
13
Ok terima kasih. Ini bekerja dengan baik. Itu akan mendapatkan orientasi saat ini. getResources (). getConfiguration (). Orientasi
Jared
7
Cermat! Anda perlu membedakan antara apa yang dikembalikan getConfiguration () dan apa yang diinginkan setRequestedOrientation - lihat jawaban saya di bawah untuk detailnya
Andy Weinstein
ada masalah dengan pendekatan ini. Pastikan Anda membaca komentar dari jawaban ini
Bugs Happen
tetapi itu menetapkan orientasi yang sama untuk semua aktivitas, adakah cara lain di mana kita dapat mengubah orientasi
silverFoxA
106

Hati-hati dengan perbedaan antara apa yang dikembalikan getConfiguration dan apa yang diinginkan setRequestedOrientation - keduanya int, tetapi berasal dari definisi konstanta yang berbeda.

Berikut ini cara mengunci orientasi saat ini, sambil memungkinkan membalik 180 derajat

int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else {
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
Andy Weinstein
sumber
13
Anda mungkin lebih suka menggunakan SCREEN_ORIENTATION_USER_LANDSCAPE karena ini tidak memungkinkan membalik 180 derajat jika pengguna telah menonaktifkan rotasi layar di pengaturan. Demikian pula saat beralih kembali ke rotasi bebas, SCREEN_ORIENTATION_USER lebih baik daripada SCREEN_ORIENTATION_SENSOR karena SCREEN_ORIENTATION_SENSOR memungkinkan rotasi bebas meskipun setelan melarang.
Steve Waring
Cemerlang! Perlu menambahkan bahwa ketika Anda beralih ke konfigurasi ulang orientasi terbalik tidak terjadi. Setidaknya pada perangkat yang saya uji. Sangat penting untuk mengetahui apakah Anda ingin menghentikan konfigurasi ulang selama beberapa dialog ditampilkan, dll
sberezin
47

Ini berfungsi pada perangkat dengan potret terbalik dan lanskap terbalik.

Orientasi kunci:

    int orientation = getActivity().getRequestedOrientation();
    int rotation = ((WindowManager) getActivity().getSystemService(
            Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
    switch (rotation) {
    case Surface.ROTATION_0:
        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        break;
    case Surface.ROTATION_90:
        orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        break;
    case Surface.ROTATION_180:
        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
        break;
    default:
        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
        break;
    }

    getActivity().setRequestedOrientation(orientation);

Buka kunci orientasi:

   getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
pstoppani.dll
sumber
5
Dapatkan "Returns the rotation of the screen from its "natural" orientation." sumber rotasi . Jadi pada ponsel yang mengatakan ROTATION_0 adalah potret mungkin benar, tetapi pada tablet orientasinya "alami" kemungkinan adalah lanskap dan ROTATION_0 harus mengembalikan lanskap, bukan potret.
jp36
@ jp36, saya uji pada Nexus 7 yang memiliki orientasi alami yang sama dengan telepon. Terima kasih telah menguji pada tablet yang lebih besar (yang tidak saya miliki).
pstoppani
1
Seperti yang dikatakan jp36, ini tidak berfungsi pada tablet dengan orientasi lanskap alami!
DominicM
Bagaimana cara menguji potret terbalik di perangkat ??
AndyBoy
27

Saya sepertinya pernah mengalami kasus serupa. Saya ingin mendukung orientasi apa pun, tetapi saya harus tetap dalam orientasi saat ini setelah titik tertentu dalam alur kerja. Solusi saya adalah:

Saat masuk ke alur kerja yang dilindungi:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

Saat keluar dari alur kerja yang dilindungi:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
stefan bachert
sumber
2
Ini tidak membahas OQ, setidaknya di Android> = 16. setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) mungkin menyetel perangkat ke lanskap meskipun dalam mode potret, sedangkan pertanyaan merujuk pada orientasi penguncian yang diberikan.
greg7gkb
3
bagi saya, menyetelnya ke nosensor membawa saya kembali ke mode potret jika saya dalam mode lanskap, saya menggunakan SCREEN_ORIENTATION_LOCKED sebagai gantinya dan berfungsi untuk saya
Jimmar
1
@JiMMaR SCREEN_ORIENTATION_LOCKED adalah cara terbaik untuk Android> = 18. Tetapi jika Anda menargetkan sesuatu yang lebih rendah, itu tidak akan berhasil. Saya sarankan menggunakan jawaban jp36 di bawah ini.
Patrick Boos
23

Alternatif jawaban @pstoppani dengan dukungan untuk tablet (Seperti jawaban @pstoppani, ini hanya akan berfungsi pada perangkat> 2.2)
-Diuji Samsung Galaxy SIIIdanSamsung Galaxy Tab 10.1

public static void lockOrientation(Activity activity) {
    Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    int rotation = display.getRotation();
    int tempOrientation = activity.getResources().getConfiguration().orientation;
    int orientation = 0;
    switch(tempOrientation)
    {
    case Configuration.ORIENTATION_LANDSCAPE:
        if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90)
            orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        else
            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
        break;
    case Configuration.ORIENTATION_PORTRAIT:
        if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270)
            orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        else
            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
    }
    activity.setRequestedOrientation(orientation);
}
jp36
sumber
Terima kasih, Ini bekerja dengan baik tapi aku tidak mengerti bahwa mengapa cek dengan ||di rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90dan dengan rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270. Jadi saya punya 2 keraguan :::: pertama, Mengapa ROTATION_0bukan ROTATION_180di kasus kedua dan satu lagi mengapa memeriksa 0 derajat dengan 90 bukan 180 ??
AndyBoy
@AndyBoy itu ada hubungannya dengan orientasi default perangkat. Biasanya ponsel memiliki orientasi potret default yang berarti rotasi mengembalikan nol untuk potret, tetapi beberapa tablet memiliki default lanskap yang berarti rotasi mengembalikan nol untuk lanskap. Jadi, ||pemeriksaan yang berbeda menangani dua kemungkinan orientasi default berdasarkan pada perangkat yang melaporkan lanskap vs potret.
jp36
5

Ini kode saya, Anda dapat mengunci dengan salah satu metode ini layar Anda dan setelah menyelesaikan tugas buka kunci dengan unlockOrientation:

/** Static methods related to device orientation. */
public class OrientationUtils {
    private OrientationUtils() {}

    /** Locks the device window in landscape mode. */
    public static void lockOrientationLandscape(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    /** Locks the device window in portrait mode. */
    public static void lockOrientationPortrait(Activity activity) {
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    /** Locks the device window in actual screen mode. */
    public static void lockOrientation(Activity activity) {
        final int orientation = activity.getResources().getConfiguration().orientation;
        final int rotation = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();

        // Copied from Android docs, since we don't have these values in Froyo 2.2
        int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
        int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;

        // Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO
        if (!BuildVersionUtils.hasGingerbread()) {
            SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }

        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90){
            if (orientation == Configuration.ORIENTATION_PORTRAIT){
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
            else if (orientation == Configuration.ORIENTATION_LANDSCAPE){
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }
        }
        else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270) 
        {
            if (orientation == Configuration.ORIENTATION_PORTRAIT){
                activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
            }
            else if (orientation == Configuration.ORIENTATION_LANDSCAPE){
                activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
            }
        }
    }

    /** Unlocks the device window in user defined screen mode. */
    public static void unlockOrientation(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
    }

}
orang gila
sumber
0

Berikut konversi Xamarin dari jawaban @pstoppani di atas.

CATATAN: ini untuk Fragmen, ganti Aktivitas. dengan ini. jika digunakan dalam suatu aktivitas.

public void LockRotation()
{
    ScreenOrientation orientation;

    var surfaceOrientation = Activity.WindowManager.DefaultDisplay.Rotation;

    switch (surfaceOrientation) {
        case SurfaceOrientation.Rotation0:
            orientation = ScreenOrientation.Portrait;
            break;
        case SurfaceOrientation.Rotation90:
            orientation = ScreenOrientation.Landscape;
            break;
        case SurfaceOrientation.Rotation180:
            orientation = ScreenOrientation.ReversePortrait;
            break;
        default:
            orientation = ScreenOrientation.ReverseLandscape;
            break;
    }

    Activity.RequestedOrientation = orientation;
}

public void UnlockRotation()
{
    Activity.RequestedOrientation = ScreenOrientation.Unspecified;
}

Ini belum teruji karena pergi dengan pendekatan yang berbeda sebelum digunakan, tetapi mungkin berguna.

WickedW
sumber
Ini adalah jawaban yang sama dengan jawaban pstoppani, dan akan gagal di tablet.
Tim Autin