Tabletlerin dikey ve yatay (sw600dp veya üstü) görüntüde görüntülenmesini istiyorum, ancak telefonların yalnızca portre ile sınırlı olması gerekir. Koşullu olarak bir yönlendirme seçmenin bir yolunu bulamıyorum. Baska öneri?
Tabletlerin dikey ve yatay (sw600dp veya üstü) görüntüde görüntülenmesini istiyorum, ancak telefonların yalnızca portre ile sınırlı olması gerekir. Koşullu olarak bir yönlendirme seçmenin bir yolunu bulamıyorum. Baska öneri?
Yanıtlar:
Kaynakları ve boyut niteleyicileri kullanmanın iyi bir yolu .
Bu bool kaynağını res / değerleri içine bools.xml veya başka bir şekilde yerleştirin (dosya adları burada önemli değildir):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
Bunu res / değerleri-sw600dp ve res / değerleri-xlarge içine koyun:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
Android Studio'da bu dizinleri ve dosyaları ekleme konusunda yardım için bu ek cevaba bakın .
Ardından, Etkinliklerinizin onCreate yönteminde şunları yapabilirsiniz:
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
En küçük genişlik yönünde 600 dp'den fazla veya Android 3.2 öncesi cihazlarda (temel olarak tabletler) x-büyük olan cihazlar , sensör ve kullanıcı kilitli dönüşe vb . Dayalı olarak normal gibi davranacaktır . Diğer her şey (telefonlar, hemen hemen) sadece portre olacaktır.
xlarge
yoksa sadece kullanabilir sw600dp
miyim? Muhtemelen bu günlerde <3,2 çalışan herhangi bir tablet yoktur.
onCreate()
. Çağrıyı setRequestedOrientation()
zaman ve bağlamda farklı bir konuma taşıdığımda, yeniden başlatma artık gerçekleşmedi.
Önce cihazın ekran boyutunu elde etmek için bu şekilde deneyebilirsiniz
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();
}
ve ardından yönlendirmeyi buna göre ayarlayın
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Configuration
sağlar screenLayout
bilgiler - DPI. Oysa soru fiziksel cihaz ekran boyutu - telefon VS tablet ile ilgilidir. Yani, bir olabilir Configuration.SCREENLAYOUT_SIZE_NORMAL
ve bir MDPI tablet olurdu.
Dosyalarını res/values-sw600dp
ve res/values-large
dizinlerini eklemek için Android Studio'da aşağıdaki adımları uygulayabilirsiniz bools.xml
.
Her şeyden önce, Proje sekmesinden gezgindeki Proje (Android yerine) filtresini seçin.
Ardından app/src/main/res
dizini sağ tıklayın . Yeni > Android Kaynak Dizini'ni seçin .
En Küçük Ekran Genişliği'ni seçin ve ardından >> düğmesine basın .
Yazın 600
en küçük ekran genişliği için. Dizin adı otomatik olarak oluşturulur. Tamam de.
Ardından yeni oluşturulan values-sw600dp
dosyayı sağ tıklayın . Yeni > Değerler kaynak dosyası'nı seçin . Tip bools
adı için.
Bir values-large
dizin eklemek yalnızca Android 3.2 öncesi (API seviye 13) destekliyorsanız gereklidir. Aksi takdirde bu adımı atlayabilirsiniz. values-large
Dizin tekabül values-sw600dp
. ( values-xlarge
karşılık gelir values-sw720dp
.)
values-large
Dizini oluşturmak için yukarıdakiyle aynı adımları izleyin, ancak bu durumda En Küçük Ekran Genişliği yerine Boyut'u seçin . Seç Büyük . Dizin adı otomatik olarak oluşturulur.
bools.xml
Dosyayı oluşturmak için önceki gibi sağ tıklayın .
İşte nasıl yaptım ( http://androidblogger.blogspot.com/2011/08/orientation-for-both-phones-and-tablets.html'den esinlenerek ):
AndroidManifest.xml dosyasında, portre ve manzara arasında değiştirmek istediğiniz her etkinlik için (screenSize eklediğinizden emin olun - buna ihtiyacınız yoktu!) Burada bir ekran yönü ayarlamanıza gerek yoktur. :
android:configChanges="keyboardHidden|orientation|screenSize"
Her Faaliyete eklenecek yöntemler:
public static boolean isXLargeScreen(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
ve: (bu yöntemi geçersiz kılmazsanız, uygulama yön değiştirirken onCreate () yöntemini çağırır)
@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
}
Her bir Etkinliğin onCreate () öğesinde:
if (!isXLargeScreen(getApplicationContext())) { //set phones to portrait;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
else {
//I set background images here depending on portrait or landscape orientation
}
Anlayamadığım tek şey, uygulamanın yataydan portreye veya tersi yönde geçiş yaparken düzen dosyalarını değiştirmesini sağlamaktır. Cevabın yukarıdaki bağlantıya benzer bir şey yaptığını varsayıyorum, ancak bunu benim için çalıştıramadım - tüm verilerimi sildi. Ancak, portre ve manzara için aynı düzen dosyasına sahip olduğunuz kadar basit bir uygulamanız varsa, bu işe yaramalıdır.
Ginny'nin cevabını takiben , bunu yapmanın en güvenilir yolunun şöyle olduğunu düşünüyorum:
Açıklandığı gibi burada , kaynaklar sw600dp bir boole koydu. Önek sw olmalıdır, aksi takdirde düzgün çalışmaz:
res / değerleri-sw600dp / dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
</resources>
res / değerleri / dimens.xml içinde
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">false</bool>
</resources>
Ardından, bu boole'yi almak için bir yöntem yapın:
public class ViewUtils {
public static boolean isTablet(Context context){
return context.getResources().getBoolean(R.bool.isTablet);
}
}
Ve bu davranışı istediğiniz etkinliklerden genişleyecek temel etkinlik:
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!ViewUtils.isTablet(this)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
}
Böylece her etkinlik BaseActivity'yi genişletir:
public class LoginActivity extends BaseActivity //....
Önemli : Genişletseniz bile , AndroidManifest.xml dosyasında her birine BaseActivity
satır eklemeniz gerekir :android:configChanges="orientation|screenSize"
Activity
<activity
android:name=".login.LoginActivity"
android:configChanges="orientation|screenSize">
</activity>
Peki, bu biraz geç ama burada sadece XML ama setRequestedOrientation
oryantasyonu değiştirmek zorundaymış gibi bir aktiviteyi yeniden yaratmayan bir hack çözümü :
Kabul edilen cevabı takiben , kotlin dosyasını birisine yardımcı olacağını umarak çözüm ekliyorum
Bu bool kaynağı koyun res/values
olarak bools.xml (dosya isimleri burada olsun yok) ya da her neyse:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
Bunu içine koyun res/values-sw600dp
ve res/values-sw600dp-land
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
Ardından, etkinliğinizdeki veya fragmanvitedeki aşağıdaki satırlara ekleyin
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)
}
}
Diğer çözümler benim için işe yaramadı. Diyaloglar ve rekreasyon konularında hala garip bir yönelim problemim vardı. Benim çözümüm Faaliyet'i uzatmak ve onu tezahür içinde portre olarak zorlamaktı.
Misal:
public class MainActivityPhone extends MainActivity {}
Manifest.xml:
<activity
android:screenOrientation="portrait"
android:name=".MainActivityPhone"
android:theme="@style/AppTheme.NoActionBar" />
splashcreen etkinliğinde:
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);
Eski bir soru biliyorum. Yönünüzü değiştirebilse veya takas etse bile uygulamanızı her zaman portre modunda çalıştırmak için (örneğin tabletlerde) Dikey ve yatay konumun nasıl olduğunu bilmenize gerek kalmadan cihazı doğru yönde ayarlamak için kullanılan bu işlevi tasarladım. özellikler cihazda düzenlenmiştir.
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); }
}
Tıkır tıkır çalışıyor!
DİKKAT: this.activity
Etkinliğinize göre değiştirin veya ana etkinliğe ekleyin ve this.activity
;-) kaldırın
Eğer tersini yapmak istiyorsanız, kodu manzaraya değiştirmeniz gerekir (ama bunun nasıl açık olduğunu düşünüyorum).
Ne yazık ki, setRequestedOrientation (...) yönteminin kullanılması etkinliğin yeniden başlatılmasına neden olur, bu yüzden bunu onCreate yönteminde çağırsanız bile etkinlik yaşam döngüsü boyunca ilerler ve ardından aynı etkinliği istenen yönde yeniden oluşturur. Yani @Brian Christensen'ın cevabında, etkinlik kodunun iki kez çağrılabileceğini düşünmelisiniz, bunun kötü etkileri olabilir (sadece görsel değil, aynı zamanda ağ isteklerinde, analitiklerde vb.).
Ayrıca, manifChanges özniteliğini manifest'te ayarlamak, bence büyük bir yeniden dengeleme maliyetidir ve bu da büyük bir yeniden düzenleme maliyeti alabilir. Android Devs, bu özelliği değiştirmenizi önermez .
Son olarak, screenOrientation'u bir şekilde farklı ayarlamaya çalışmak (yeniden başlatma probleminden kaçınmak için) imkansızdır, değiştirilemeyen statik tezahür nedeniyle statik olarak imkansızdır, programlı olarak sadece bu yöntemi zaten başlatılmış aktivitede çağırmak mümkündür.
Özet: Bence, @Brian Christensen önerisi en iyi değiş tokuş, ancak yeniden başlatılan aktivite sorununun farkında olun.
layout-land
içinde olduğu gibi telefonlar için peyzaj düzenleri tasarlamak DEĞİLDİRres
.