Döndürmeyi İşleme
Bu konuda, Xamarin.Android'de cihaz yönlendirme değişikliklerini işleme açıklanmaktadır. Belirli bir cihaz yönlendirmesine yönelik kaynakları otomatik olarak yüklemek için Android kaynak sistemiyle çalışmayı ve yönlendirme değişikliklerini program aracılığıyla işlemeyi kapsar.
Genel bakış
Mobil cihazlar kolayca döndürülebildiğinden, yerleşik döndürme mobil işletim cihazlarında standart bir özelliktir. Android, kullanıcı arabiriminin XML'de bildirimli olarak mı yoksa kodda program aracılığıyla mı oluşturulduğuna bakılmaksızın uygulamalar içinde döndürmeyle ilgilenmek için gelişmiş bir çerçeve sağlar. Döndürülen bir cihazda bildirim temelli düzen değişikliklerini otomatik olarak işlerken, bir uygulama Android kaynak sistemiyle sıkı tümleştirmeden yararlanabilir. Programlı düzen için değişiklikler el ile işlenmelidir. Bu, çalışma zamanında daha ince denetim sağlar, ancak geliştirici için daha fazla çalışma pahasına. Uygulama ayrıca Etkinlik yeniden başlatma işlemini geri çevirmeyi ve yönlendirme değişikliklerini el ile denetlemeyi seçebilir.
Bu kılavuz aşağıdaki yönlendirme konularını inceler:
Bildirim temelli Düzen Döndürme – Belirli yönlendirmeler için hem düzenlerin hem de çizilebilir öğelerin nasıl yüklenecekleri de dahil olmak üzere yönlendirmeye duyarlı uygulamalar oluşturmak için Android kaynak sistemini kullanma.
Programlı Düzen Döndürme – Denetimleri program aracılığıyla ekleme ve yönlendirme değişikliklerini el ile işleme.
Döndürmeyi Düzenlerle Bildirimli Olarak İşleme
Adlandırma kurallarına uyan klasörlere dosya ekleyerek Android, yönlendirme değiştiğinde uygun dosyaları otomatik olarak yükler. Buna aşağıdakilerin desteklenmesi dahildir:
Düzen Kaynakları – Her yönlendirme için hangi düzen dosyalarının şişirileceğini belirtme.
Çizilebilir Kaynaklar – Her yönlendirme için hangi çizilebilir öğelerin yükleneceğini belirtme.
Düzen Kaynakları
Varsayılan olarak, Kaynaklar/düzen klasörüne dahil edilen Android XML (AXML) dosyaları bir Etkinliğin görünümlerini işlemek için kullanılır. Bu klasörün kaynakları, özellikle yatay için ek düzen kaynağı sağlanmazsa hem dikey hem de yatay yönlendirme için kullanılır. Varsayılan proje şablonu tarafından oluşturulan proje yapısını göz önünde bulundurun:
Bu proje Resources/layout klasöründe tek bir Main.axml dosyası oluşturur. Activity'in OnCreate
yöntemi çağrıldığında Main.axml dosyasında tanımlanan görünümü şişirir ve aşağıdaki XML'de gösterildiği gibi bir düğme bildirir:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/myButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>
</LinearLayout>
Cihaz yatay yönlendirmeye döndürülürse, Etkinliğin OnCreate
yöntemi yeniden çağrılır ve aşağıdaki ekran görüntüsünde gösterildiği gibi aynı Main.axml dosyası şişirilir:
Yönlendirmeye Özgü Düzenler
Düzen klasörüne ek olarak (varsayılan değer dikeydir ve adlı layout-land
bir klasör dahil edilerek açıkça layout-port olarak adlandırılabilir), bir uygulama herhangi bir kod değişikliği yapmadan yatay ortamda ihtiyaç duyduğu görünümleri tanımlayabilir.
Main.axml dosyasının aşağıdaki XML'yi içerdiğini varsayalım:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="This is portrait"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</RelativeLayout>
Projeye ek bir Main.axml dosyası içeren layout-land adlı bir klasör eklenirse, düzen yatay olduğunda şişirilirse Artık Android'in yeni eklenen Main.axml dosyasını yüklemesine neden olur. Main.axml dosyasının aşağıdaki kodu içeren yatay sürümünü düşünün (kolaylık olması için, bu XML kodun varsayılan dikey sürümüne benzer, ancak içinde TextView
farklı bir dize kullanır):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="This is landscape"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</RelativeLayout>
Bu kodu çalıştırmak ve cihazı dikeyden yataya döndürmek, aşağıda gösterildiği gibi yeni XML yüklemesini gösterir:
Çizilebilir Kaynaklar
Döndürme sırasında Android, çizilebilir kaynakları düzen kaynaklarına benzer şekilde ele alır. Bu durumda sistem, çizilebilir değerleri sırasıyla Resources/drawable ve Resources/drawable-land klasörlerinden alır.
Örneğin, projenin Resources/drawable klasöründeki Monkey.png adlı bir görüntü içerdiğini varsayalım; burada çizilebilir öğeye aşağıdaki gibi bir ImageView
XML'den başvurulur:
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/monkey"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
Monkey.png farklı bir sürümünün Resources/drawable-land altına eklendiğini de varsayalım. Düzen dosyalarında olduğu gibi, cihaz döndürüldüğünde, aşağıda gösterildiği gibi belirtilen yönlendirme için çizilebilir değişiklikler yapılır:
Döndürmeyi Program Aracılığıyla İşleme
Bazen kodda düzenleri tanımlarız. Bu, teknik sınırlamalar, geliştirici tercihi vb. dahil olmak üzere çeşitli nedenlerle gerçekleşebilir. Denetimleri program aracılığıyla eklediğimizde, bir uygulama, XML kaynaklarını kullandığımızda otomatik olarak işlenen cihaz yönlendirmesini el ile hesaba katmalıdır.
Koda Denetim Ekleme
Program aracılığıyla denetim eklemek için uygulamanın aşağıdaki adımları gerçekleştirmesi gerekir:
- Bir düzen oluşturun.
- Düzen parametrelerini ayarlayın.
- Denetimler oluşturun.
- Denetim düzeni parametrelerini ayarlayın.
- Düzene denetimler ekleyin.
- Düzeni içerik görünümü olarak ayarlayın.
Örneğin, aşağıdaki kodda gösterildiği gibi öğesine eklenen tek TextView
bir denetimden oluşan bir RelativeLayout
kullanıcı arabirimini göz önünde bulundurun.
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// create a layout
var rl = new RelativeLayout (this);
// set layout parameters
var layoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.FillParent);
rl.LayoutParameters = layoutParams;
// create TextView control
var tv = new TextView (this);
// set TextView's LayoutParameters
tv.LayoutParameters = layoutParams;
tv.Text = "Programmatic layout";
// add TextView to the layout
rl.AddView (tv);
// set the layout as the content view
SetContentView (rl);
}
Bu kod bir RelativeLayout
sınıfın örneğini oluşturur ve özelliğini LayoutParameters
ayarlar. sınıfı LayoutParams
, Android'in denetimlerin yeniden kullanılabilir bir şekilde konumlandırılma şeklini kapsülleme yöntemidir. Düzenin bir örneği oluşturulduktan sonra denetimler oluşturulabilir ve buna eklenebilir. Denetimler, bu örnekteki gibi öğesine TextView
de sahiptirLayoutParameters
. TextView
oluşturulduktan sonra, öğesini öğesine ekleyin RelativeLayout
ve içerik görünümü olarak ayarını RelativeLayout
yapın, uygulamanın gösterildiği gibi öğesini görüntülemesine TextView
neden olur:
Kodda Yönlendirmeyi Algılama
Bir uygulama çağrıldığında OnCreate
her yönlendirme için farklı bir kullanıcı arabirimi yüklemeye çalışırsa (cihaz her döndürüldüğünde bu gerçekleşir), yönlendirmeyi algılamalı ve ardından istenen kullanıcı arabirimi kodunu yüklemelidir. Android, aşağıda gösterildiği gibi özelliği aracılığıyla geçerli cihaz döndürmesini WindowManager.DefaultDisplay.Rotation
belirlemek için kullanılabilen adlı WindowManager
bir sınıfa sahiptir:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// create a layout
var rl = new RelativeLayout (this);
// set layout parameters
var layoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.FillParent);
rl.LayoutParameters = layoutParams;
// get the initial orientation
var surfaceOrientation = WindowManager.DefaultDisplay.Rotation;
// create layout based upon orientation
RelativeLayout.LayoutParams tvLayoutParams;
if (surfaceOrientation == SurfaceOrientation.Rotation0 || surfaceOrientation == SurfaceOrientation.Rotation180) {
tvLayoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
} else {
tvLayoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
tvLayoutParams.LeftMargin = 100;
tvLayoutParams.TopMargin = 100;
}
// create TextView control
var tv = new TextView (this);
tv.LayoutParameters = tvLayoutParams;
tv.Text = "Programmatic layout";
// add TextView to the layout
rl.AddView (tv);
// set the layout as the content view
SetContentView (rl);
}
Bu kod, ekranın sol üst kısmından 100 piksel olacak şekilde ayarlar TextView
ve burada gösterildiği gibi yataya döndürüldüğünde yeni düzene otomatik olarak animasyon oluşturur:
Etkinlik Yeniden Başlatmayı Önleme
uygulamasındaki OnCreate
her şeyi işlemeye ek olarak, bir uygulama aşağıdaki gibi ayarlayarak ConfigurationChanges
yönlendirme değiştiğinde etkinliğin yeniden başlatılmasını ActivityAttribute
da engelleyebilir:
[Activity (Label = "CodeLayoutActivity", ConfigurationChanges=Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
Artık cihaz döndürüldüğünde Etkinlik yeniden başlatılmaz. Bu durumda yönlendirme değişikliğini el ile işlemek için, bir Activity aşağıdaki Etkinliğin OnConfigurationChanged
yeni uygulamasında olduğu gibi yöntemini geçersiz kılabilir ve geçirilen nesneden Configuration
yönlendirmeyi belirleyebilir:
[Activity (Label = "CodeLayoutActivity", ConfigurationChanges=Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
public class CodeLayoutActivity : Activity
{
TextView _tv;
RelativeLayout.LayoutParams _layoutParamsPortrait;
RelativeLayout.LayoutParams _layoutParamsLandscape;
protected override void OnCreate (Bundle bundle)
{
// create a layout
// set layout parameters
// get the initial orientation
// create portrait and landscape layout for the TextView
_layoutParamsPortrait = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
_layoutParamsLandscape = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
_layoutParamsLandscape.LeftMargin = 100;
_layoutParamsLandscape.TopMargin = 100;
_tv = new TextView (this);
if (surfaceOrientation == SurfaceOrientation.Rotation0 || surfaceOrientation == SurfaceOrientation.Rotation180) {
_tv.LayoutParameters = _layoutParamsPortrait;
} else {
_tv.LayoutParameters = _layoutParamsLandscape;
}
_tv.Text = "Programmatic layout";
rl.AddView (_tv);
SetContentView (rl);
}
public override void OnConfigurationChanged (Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged (newConfig);
if (newConfig.Orientation == Android.Content.Res.Orientation.Portrait) {
_tv.LayoutParameters = _layoutParamsPortrait;
_tv.Text = "Changed to portrait";
} else if (newConfig.Orientation == Android.Content.Res.Orientation.Landscape) {
_tv.LayoutParameters = _layoutParamsLandscape;
_tv.Text = "Changed to landscape";
}
}
}
TextView's
Burada düzen parametreleri hem yatay hem de dikey için başlatılır. Sınıf değişkenleri, yönlendirme değiştiğinde Etkinlik yeniden oluşturulmayacağı için parametreleri kendileriyle TextView
birlikte tutar. Kod, için başlangıç düzenini ayarlamak için yine de in OnCreate
kullanır surfaceOrientartion
TextView
. Bundan sonra, OnConfigurationChanged
sonraki tüm düzen değişikliklerini işler.
Uygulamayı çalıştırdığımızda Android, cihaz döndürme gerçekleşirken kullanıcı arabirimi değişikliklerini yükler ve Etkinliği yeniden başlatmaz.
Bildirim Temelli Düzenler için Etkinlik Yeniden Başlatmasını Önleme
Düzeni XML'de tanımlarsak cihaz döndürmenin neden olduğu etkinlik yeniden başlatmaları da önlenebilir. Örneğin, etkinliğin yeniden başlatılmasını önlemek (performans nedeniyle, belki de) ve farklı yönlendirmeler için yeni kaynaklar yüklememiz gerekmiyorsa bu yaklaşımı kullanabiliriz.
Bunu yapmak için programlı düzende kullandığımız yordamın aynısını uygularız. Daha önce yaptığımız CodeLayoutActivity
gibi içinde ayarlamanız ConfigurationChanges
ActivityAttribute
yeterlidir. Yönlendirme değişikliği için çalıştırılması gereken tüm kodlar yönteminde OnConfigurationChanged
yeniden uygulanabilir.
Yönlendirme Değişiklikleri Sırasında Durumu Koruma
İster bildirim temelli ister programlı olarak döndürme işlensin, tüm Android uygulamaları cihaz yönlendirmesi değiştiğinde durumu yönetmek için aynı teknikleri uygulamalıdır. Bir Android cihazı döndürüldüğünde sistem çalışan bir Etkinliği yeniden başlattığından, durumu yönetmek önemlidir. Android bunu, belirli bir yönlendirme için özel olarak tasarlanmış düzenler ve çizilebilir öğeler gibi alternatif kaynakları yüklemeyi kolaylaştırmak için yapar. Etkinlik yeniden başlatıldığında yerel sınıf değişkenlerinde depolamış olabileceği geçici durumları kaybeder. Bu nedenle, bir Etkinlik durum dayanıklıysa, durumunu uygulama düzeyinde kalıcı hale getirir. Bir uygulamanın, yönlendirme değişiklikleri arasında korumak istediği herhangi bir uygulama durumunu kaydetmeyi ve geri yüklemeyi işlemesi gerekir.
Android'de kalıcı durum hakkında daha fazla bilgi için Etkinlik Yaşam Döngüsü kılavuzuna bakın.
Özet
Bu makalede, döndürmeyle çalışmak için Android'in yerleşik özelliklerinin nasıl kullanılacağı ele alınmıştır. İlk olarak, Yönlendirme kullanan uygulamalar oluşturmak için Android kaynak sisteminin nasıl kullanılacağını açıkladı. Ardından koda denetimlerin nasıl ekleneceği ve yönlendirme değişikliklerinin el ile nasıl işleneceği sunuldu.