Saya ingin tablet dapat ditampilkan dalam potret dan lanskap (sw600dp atau lebih tinggi), tetapi ponsel dibatasi hanya untuk potret. Saya tidak dapat menemukan cara untuk memilih orientasi secara kondisional. Ada saran?
Saya ingin tablet dapat ditampilkan dalam potret dan lanskap (sw600dp atau lebih tinggi), tetapi ponsel dibatasi hanya untuk potret. Saya tidak dapat menemukan cara untuk memilih orientasi secara kondisional. Ada saran?
Jawaban:
Berikut cara yang baik menggunakan sumber daya dan ukuran kualifikasi .
Masukkan sumber bool ini dalam res / nilai sebagai bools.xml atau apa pun (nama file tidak masalah di sini):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
Letakkan ini di res / values-sw600dp dan res / values-xlarge:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
Lihat jawaban tambahan ini untuk membantu menambahkan direktori dan file ini di Android Studio.
Kemudian, dalam metode onCreate dari Aktivitas Anda, Anda dapat melakukan ini:
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Perangkat yang lebih dari 600 dp dalam arah lebar terkecil, atau x-besar pada perangkat pra-Android 3.2 (tablet, pada dasarnya) akan berperilaku seperti biasa, berdasarkan sensor dan rotasi yang dikunci pengguna, dll . Segala sesuatu yang lain (telepon, cukup banyak) akan menjadi potret saja.
xlarge
juga atau bisakah saya menggunakan sw600dp
? Mungkin tidak ada tablet yang menjalankan <3.2 hari ini.
onCreate()
. Ketika saya memindahkan panggilan ke setRequestedOrientation()
posisi yang berbeda dalam waktu dan konteks, restart tidak terjadi lagi.
Anda dapat mencoba cara ini terlebih dahulu untuk mendapatkan ukuran layar perangkat
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
Toast.makeText(this, "Large screen",Toast.LENGTH_LONG).show();
}
else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
Toast.makeText(this, "Normal sized screen" , Toast.LENGTH_LONG).show();
}
else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
Toast.makeText(this, "Small sized screen" , Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, "Screen size is neither large, normal or small" , Toast.LENGTH_LONG).show();
}
dan kemudian mengatur orientasi sesuai dengan itu
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Configuration
memberikan screenLayout
informasi - DPI. Sedangkan pertanyaannya terkait dengan ukuran layar perangkat fisik - ponsel VS tablet. Artinya, Anda dapat memiliki Configuration.SCREENLAYOUT_SIZE_NORMAL
dan itu akan menjadi tablet MDPI.
Anda dapat melakukan langkah-langkah berikut di Android Studio untuk menambahkan res/values-sw600dp
dan res/values-large
direktori dengan bools.xml
file mereka .
Pertama-tama, dari tab Project pilih filter Project (bukan Android) di navigator.
Kemudian klik kanan app/src/main/res
direktori tersebut. Pilih Baru > Direktori Sumber Daya Android .
Pilih Lebar Layar Terkecil , lalu tekan tombol >> .
Ketik 600
lebar layar terkecil. Nama direktori akan dibuat secara otomatis. Katakan OK
Kemudian klik kanan pada file yang baru dibuat values-sw600dp
. Pilih Baru > File sumber daya Nilai . Ketikkan bools
nama.
Menambahkan values-large
direktori hanya diperlukan jika Anda mendukung pra Android 3.2 (API level 13). Kalau tidak, Anda dapat melewati langkah ini. The values-large
direktori sesuai dengan values-sw600dp
. ( values-xlarge
sesuai dengan values-sw720dp
.)
Untuk membuat values-large
direktori, ikuti langkah-langkah yang sama seperti di atas, tetapi dalam hal ini pilih Ukuran daripada Lebar Layar Terkecil. Pilih Besar . Nama direktori akan dibuat secara otomatis.
Klik kanan direktori seperti sebelumnya untuk membuat bools.xml
file.
Begini cara saya melakukannya (terinspirasi oleh http://androidblogger.blogspot.com/2011/08/orientation-for-both-phones-and-tablets.html ):
Di AndroidManifest.xml, untuk setiap aktivitas Anda ingin dapat mengubah antara potret dan lanskap (pastikan Anda menambahkan screenSize - Anda tidak membutuhkannya!) Anda tidak perlu mengatur orientasi layar di sini. :
android:configChanges="keyboardHidden|orientation|screenSize"
Metode untuk ditambahkan di setiap Aktivitas:
public static boolean isXLargeScreen(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
dan: (jika Anda tidak menimpa metode ini, aplikasi akan memanggil onCreate () saat mengubah orientasi)
@Override
public void onConfigurationChanged (Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
if (!isXLargeScreen(getApplicationContext()) ) {
return; //keep in portrait mode if a phone
}
//I set background images for landscape and portrait here
}
Di onCreate () dari setiap Kegiatan:
if (!isXLargeScreen(getApplicationContext())) { //set phones to portrait;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
else {
//I set background images here depending on portrait or landscape orientation
}
Satu-satunya hal yang saya tidak tahu adalah bagaimana cara mendapatkan aplikasi untuk mengubah file tata letak ketika beralih dari landscape ke portrait atau sebaliknya. Saya menganggap jawabannya adalah melakukan sesuatu yang mirip dengan apa yang dilakukan tautan di atas, tetapi saya tidak bisa membuatnya bekerja untuk saya - itu menghapus semua data saya. Tetapi jika Anda memiliki aplikasi yang cukup sederhana sehingga Anda memiliki file tata letak yang sama untuk potret dan lansekap, ini seharusnya berfungsi.
Mengikuti jawaban Ginny , saya pikir cara yang paling dapat diandalkan untuk melakukannya adalah sebagai berikut:
Seperti dijelaskan di sini , letakkan boolean di sumber sw sw00dp Itu harus memiliki awalan sw kalau tidak itu tidak akan berfungsi dengan baik:
dalam res / values-sw600dp / dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
</resources>
dalam res / values / dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">false</bool>
</resources>
Kemudian buat metode untuk mengambil boolean itu:
public class ViewUtils {
public static boolean isTablet(Context context){
return context.getResources().getBoolean(R.bool.isTablet);
}
}
Dan aktivitas dasar untuk memperluas dari aktivitas di mana Anda menginginkan perilaku ini:
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!ViewUtils.isTablet(this)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
}
Jadi setiap aktivitas akan memperluas BaseActivity:
public class LoginActivity extends BaseActivity //....
Penting : meskipun Anda memperluas dari BaseActivity
, Anda harus menambahkan baris android:configChanges="orientation|screenSize"
ke masing-masing Activity
di AndroidManifest.xml Anda:
<activity
android:name=".login.LoginActivity"
android:configChanges="orientation|screenSize">
</activity>
Yah, ini agak terlambat, tetapi, ini adalah XML-Only tetapi solusi peretasan yang tidak menciptakan kembali aktivitas seperti setRequestedOrientation
halnya jika harus mengubah orientasi:
Mengikuti jawaban yang diterima , saya menambahkan file kotlin dengan solusinya semoga membantu seseorang
Masukkan sumber bool ini res/values
sebagai bools.xml atau apa pun (nama file tidak penting di sini):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
Masukkan ini res/values-sw600dp
dan res/values-sw600dp-land
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
Kemudian, tambahkan di bawah garis dalam aktivitas atau fragmentvity Anda
class MyActivity : Activity() {
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
if (resources.getBoolean(R.bool.portrait_only)) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
super.onCreate(savedInstanceState)
}
@SuppressLint("SourceLockedOrientationActivity")
override fun onConfigurationChanged(newConfig: Configuration) {
if (resources.getBoolean(R.bool.portrait_only)) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
super.onConfigurationChanged(newConfig)
}
}
Solusi lain tidak berhasil untuk saya. Saya masih memiliki beberapa masalah orientasi aneh dengan dialog dan masalah rekreasi. Solusi saya adalah memperluas Aktivitas, memaksanya sebagai potret dalam manifes.
Contoh:
public class MainActivityPhone extends MainActivity {}
manifes.xml:
<activity
android:screenOrientation="portrait"
android:name=".MainActivityPhone"
android:theme="@style/AppTheme.NoActionBar" />
dalam kegiatan splashcreen:
Intent i = null;
boolean isTablet = getResources().getBoolean(R.bool.is_tablet);
if (!isTablet)
i = new Intent(this, MainActivityPhone.class);
else
i = new Intent(this, MainActivity.class);
startActivity(i);
Pertanyaan lama yang saya tahu. Untuk menjalankan aplikasi Anda selalu dalam mode potret bahkan ketika orientasi mungkin atau sedang ditukar dll (misalnya pada tablet) Saya merancang fungsi ini yang digunakan untuk mengatur perangkat dalam orientasi yang benar tanpa perlu tahu bagaimana potret dan lansekap fitur disusun pada perangkat.
private void initActivityScreenOrientPortrait()
{
// Avoid screen rotations (use the manifests android:screenOrientation setting)
// Set this to nosensor or potrait
// Set window fullscreen
this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
DisplayMetrics metrics = new DisplayMetrics();
this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
// Test if it is VISUAL in portrait mode by simply checking it's size
boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.widthPixels );
if( !bIsVisualPortrait )
{
// Swap the orientation to match the VISUAL portrait mode
if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT )
{ this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); }
else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); }
}
else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); }
}
Bekerja seperti pesona!
PEMBERITAHUAN: Ubah this.activity
aktivitas Anda atau tambahkan aktivitas utama dan hapus this.activity
;-)
Jika Anda ingin melakukan yang sebaliknya, Anda harus mengubah kode ke lansekap (tapi saya pikir sudah jelas caranya).
Sayangnya, menggunakan metode setRequestedOrientation (...) akan menyebabkan aktivitas dimulai ulang, jadi meskipun Anda menyebut ini dalam metode onCreate, ia akan melalui siklus hidup aktivitas dan kemudian akan membuat kembali aktivitas yang sama dengan orientasi yang diminta. Jadi pada jawaban @Brian Christensen Anda harus mempertimbangkan bahwa kode aktivitas mungkin dipanggil dua kali, ini dapat memiliki efek buruk (tidak hanya visual, tetapi juga pada permintaan jaringan, analitik, dll.).
Selain itu, untuk menetapkan atribut configChanges dalam manifes menurut saya merupakan trade-off besar, yang bisa memakan biaya besar untuk refactoring. Android Devs tidak merekomendasikan untuk mengubah atribut itu .
Akhirnya, mencoba untuk mengatur screenOrientation entah bagaimana berbeda (untuk menghindari masalah restart) tidak mungkin, secara statis tidak mungkin karena manifes statis yang tidak dapat diubah, secara terprogram hanya mungkin untuk memanggil metode itu dalam aktivitas yang sudah dimulai.
Ringkasan: Menurut pendapat saya, saran @Brian Christensen adalah trade-off terbaik, tetapi berhati-hatilah dengan masalah aktivitas memulai kembali.
layout-land
di dalamres
.