Görünümlerdeki Düzenler
Düzen, uygulamanızdaki bir kullanıcı arayüzünün yapısını (ör. bir etkinlikteki) tanımlar. Düzendeki tüm öğeler,
View ve
ViewGroup nesnelerinden oluşan bir hiyerarşi kullanılarak oluşturulur.
View genellikle kullanıcının görebileceği ve etkileşimde bulunabileceği
bir şeyi çizer.
ViewGroup, şekil 1'de gösterildiği gibi
View ve diğer
ViewGroup nesnelerinin düzen yapısını tanımlayan görünmez bir kapsayıcıdır.
View nesneleri genellikle widget'lar olarak adlandırılır ve
Button veya
TextView gibi birçok alt sınıftan biri olabilir.
ViewGroup nesneleri genellikle düzen olarak adlandırılır ve
LinearLayout veya
ConstraintLayout gibi farklı düzen yapısı sağlayan birçok türden biri olabilir.
Bir düzeni iki şekilde bildirebilirsiniz:
- Kullanıcı arayüzü öğelerini XML biçiminde tanımlayın. Android,
Viewsınıflarına ve alt sınıflarına karşılık gelen basit bir XML sözlüğü sağlar (ör. widget'lar ve düzenler için). Ayrıca, sürükle ve bırak özellikli bir arayüz kullanarak XML düzeninizi oluşturmak için Android Studio'nun Düzen Düzenleyici'sini de kullanabilirsiniz.
- Çalışma zamanında düzen öğelerini örneklendirmek. Uygulamanız,
Viewve
ViewGroupnesneleri oluşturup bunların özelliklerini programatik olarak değiştirebilir.
Kullanıcı arayüzünüzü XML kullanarak bildirmek, uygulamanızın sunumunu, davranışını kontrol eden koddan ayırmanıza olanak tanır. XML dosyaları kullanmak, farklı ekran boyutları ve yönleri için farklı düzenler sağlamayı da kolaylaştırır. Bu, Farklı ekran boyutlarını destekleme bölümünde daha ayrıntılı bir şekilde ele alınmaktadır.
Android çerçevesi, uygulamanızın kullanıcı arayüzünü oluşturmak için bu yöntemlerden birini veya ikisini birden kullanma esnekliği sağlar. Örneğin, uygulamanızın varsayılan düzenlerini XML olarak beyan edebilir ve ardından çalışma zamanında düzeni değiştirebilirsiniz.
XML'i yazma
Android'in XML sözlüğünü kullanarak, kullanıcı arayüzü düzenlerini ve içerdikleri ekran öğelerini, iç içe yerleştirilmiş bir dizi öğe içeren HTML biçiminde web sayfaları oluşturduğunuz şekilde hızlı bir şekilde tasarlayabilirsiniz.
Her düzen dosyası, tam olarak bir kök öğe içermelidir ve bu öğe,
View veya
ViewGroup nesnesi olmalıdır. Kök öğeyi tanımladıktan sonra, düzeninizi tanımlayan bir
View hiyerarşisini kademeli olarak oluşturmak için alt öğe olarak ilave düzen nesneleri veya widget'lar ekleyebilirsiniz. Örneğin,
TextView ve
Button öğelerini tutmak için dikey
LinearLayout kullanan bir XML düzenini burada görebilirsiniz:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a Button" /> </LinearLayout>
Düzeninizi XML'de tanımladıktan sonra düzgün derlenebilmesi için, dosyayı Android projenizin
res/layout/ dizinine
.xml uzantısıyla kaydedin.
Düzen XML dosyasının söz dizimi hakkında daha fazla bilgi için Düzen kaynağı bölümüne bakın.
XML kaynağını yükleme
Uygulamanızı derlediğinizde, her XML düzen dosyası bir
View kaynağında derlenir. Uygulamanızın
Activity.onCreate()
geri çağırma uygulamasındaki düzen kaynağını yükleyin. Bunu yapmak için
setContentView() yöntemini çağırın ve referansı şu biçimdeki düzen kaynağınıza iletin:
R.layout.layout_file_name. Örneğin, XML düzeniniz
main_layout.xml olarak kaydedilmişse
Activity düzeniniz için aşağıdaki gibi yükleyin:
Kotlin
fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.main_layout) }
Java
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); }
Activity başlatıldığında Android çerçevesi,
Activity içindeki
onCreate() geri çağırma yöntemini çağırır. Etkinlik yaşam döngüleri hakkında daha fazla bilgi için Etkinliklere giriş bölümünü inceleyin.
Özellikler
Her
View ve
ViewGroup nesnesi, kendi tür XML özelliklerini destekler. Bazı özellikler bir
View nesnesine özgüdür. Örneğin
TextView,
textSize özelliğini destekler. Bununla birlikte, bu özellikler bu sınıfı genişleten
View nesneleri tarafından da devralınır. Bazıları
id özelliği gibi kök
View sınıfından devralındıkları için tüm
View nesnelerinde ortaktır. Diğer özellikler düzen parametreleri olarak kabul edilir. Bunlar, nesnenin üst
ViewGroup nesnesi tarafından tanımlanan şekilde
View nesnesinin belirli düzen yönlerini tanımlayan özelliklerdir.
ID
Ağaç içinde
View öğesini benzersiz bir şekilde tanımlamak için herhangi bir
View nesnesinin kendisiyle ilişkilendirilmiş bir tam sayı kimliği olabilir. Uygulama derlendiğinde bu kimliğe tam sayı olarak başvurulur. Ancak kimlik, genellikle düzen XML dosyasında
id özelliğinde bir dize olarak atanır. Bu, tüm
View nesnelerinde ortak olan bir XML özelliğidir ve
View sınıfıyla tanımlanır. Çok sık kullanıyorsunuz. Bir XML etiketi içindeki kimliğin söz dizimi şu şekildedir:
android:id="@+id/my_button"
Dizenin başındaki at sembolü (@), XML ayrıştırıcısının kimlik dizesinin geri kalanını ayrıştırıp genişlettiğini ve bunu bir kimlik kaynağı olarak tanımladığını ifade eder. Artı simgesi (+), bu adın oluşturulması ve
R.java dosyasındaki kaynaklarınıza eklenmesi gereken yeni bir kaynak adı olduğu anlamına gelir.
Android çerçevesi başka birçok kimlik kaynağı sunar. Bir Android kaynak kimliğine başvururken artı simgesine ihtiyacınız yoktur ancak
android paket ad alanını aşağıdaki gibi eklemeniz gerekir:
android:id="@android:id/empty"
android paket ad alanı, yerel kaynaklar sınıfı yerine
android.R kaynakları sınıfından bir kimliğe başvuruda bulunduğunuzu gösterir.
Uygulamanızdan görünümler oluşturmak ve bunlara referans vermek için aşağıdaki gibi genel bir kalıp kullanabilirsiniz:
- Düzen dosyasında bir görünüm tanımlayın ve bu görünüme aşağıdaki örnekte olduğu gibi benzersiz bir kimlik atayın:
<Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/>
- Görünüm nesnesinin bir örneğini oluşturun ve bunu aşağıdaki örnekte gösterildiği gibi düzenden (genellikle
onCreate()yöntemini kullanarak) yakalayın:
Kotlin
val myButton: Button = findViewById(R.id.my_button)
Java
Button myButton = (Button) findViewById(R.id.my_button);
Görünüm nesneleri için kimlik tanımlamak,
RelativeLayout oluştururken önemlidir.
Göreli bir düzende, kardeş görünümler, düzenlerini benzersiz kimlik tarafından başvurulan başka bir kardeş görünüme göre tanımlayabilir.
Bir kimliğin ağacın tamamı boyunca benzersiz olması gerekmez, ancak aradığınız ağacın parçası içinde benzersiz olmalıdır. Çoğunlukla ağacın tamamı olabileceğinden, mümkün olduğunda onu benzersiz kılmak en iyisidir.
Düzen parametreleri
layout_something adlı XML düzen özellikleri,
View için bulunduğu
ViewGroup için uygun düzen parametrelerini tanımlar.
Her
ViewGroup sınıfı,
ViewGroup.LayoutParams kapsamını genişleten iç içe yerleştirilmiş bir sınıf uygular.
Bu alt sınıf, görünüm grubu için uygun olan her bir alt görünümün boyutunu ve konumunu tanımlayan mülk türlerini içerir. Şekil 2'de gösterildiği gibi üst görünüm grubu, alt görünüm grubu dahil olmak üzere her alt görünüm için düzen parametrelerini tanımlar.
Her
LayoutParams alt sınıfı, değerleri ayarlamak için kendi söz dizimine sahiptir. Her alt öğe, kendi üst öğesi için uygun bir
LayoutParams tanımlamalıdır ancak kendi alt öğeleri için farklı bir
LayoutParams de tanımlayabilir.
Tüm görünüm grupları,
layout_width ve
layout_height kullanılarak bir genişlik ve yükseklik içerir ve her görünüm bunları tanımlamak için gereklidir. Birçok
LayoutParams, isteğe bağlı kenar boşlukları ve kenarlıklar içerir.
Kesin ölçümlerle genişliği ve yüksekliği belirtebilirsiniz, ancak bunu sık sık yapmak istemeyebilirsiniz. Daha sık olarak, genişliği veya yüksekliği ayarlamak için şu sabit değerlerden birini kullanırsınız:
wrap_content: Görünümünüzü, içeriğinin gerektirdiği boyutlara göre boyutlandırmasını sağlar.
match_parent: Görünümünüzün, üst görünüm grubunun izin verdiği ölçüde büyük olmasını sağlar.
Genel olarak, piksel gibi mutlak birimler kullanarak bir düzen genişliği ve yüksekliği belirtmenizi önermeyiz. Uygulamanızın çeşitli cihaz ekran boyutlarında düzgün bir şekilde görüntülenmesine yardımcı olduğundan, yoğunluktan bağımsız piksel birimleri (dp),
wrap_content veya
match_parent gibi göreli ölçümler kullanmak daha iyi bir yaklaşım olur. Kabul edilen ölçüm türleri Düzen kaynağında tanımlanmıştır.
Düzen konumu
Bir görünüm dikdörtgen geometriye sahiptir. Bu öğenin bir sol ve üst koordinat çiftiyle ifade edilen bir konumu ve genişlik ve yükseklik olarak ifade edilen iki boyutu vardır. Konum ve boyutlar birimi pikseldir.
getLeft() ve
getTop() yöntemlerini çağırarak bir görünümün konumunu alabilirsiniz.
İlk değer, görünümü temsil eden dikdörtgenin sol (x) koordinatını döndürür. İkinci değer, görünümü temsil eden dikdörtgenin üst (y) koordinatını döndürür. Bu yöntemler, görünümün konumunu üst öğesine göre döndürür. Örneğin,
getLeft() değeri 20 değerini döndürürse bu, görünümün doğrudan üst öğesinin sol kenarının 20 piksel sağında bulunduğu anlamına gelir.
Buna ek olarak, gereksiz hesaplamalardan kaçınmak için kullanışlı yöntemler de vardır:
getRight()
ve
getBottom().
Bu yöntemler, görünümü temsil eden dikdörtgenin sağ ve alt kenarlarının koordinatlarını döndürür. Örneğin,
getRight() çağrısı şu hesaplamaya benzer:
getLeft() + getWidth().
Boyut, dolgu ve kenar boşlukları
Bir görünümün boyutu, genişlik ve yükseklikle ifade edilir. Bir görünümde iki çift genişlik ve yükseklik değeri bulunur.
İlk çift, ölçülen genişlik ve ölçülen yükseklik olarak bilinir. Bu boyutlar, bir görünümün üst öğesi içinde ne kadar büyük olmak istediğini tanımlar. Ölçülen boyutları,
getMeasuredWidth() ve
getMeasuredHeight() numaralarını çağırarak elde edebilirsiniz.
İkinci çift, width ve height veya bazen çizim genişliği ve çizim yüksekliği olarak bilinir. Bu boyutlar, ekrandaki görünümün gerçek boyutunu çizim sırasında ve düzenden sonra tanımlar. Bu değerler, ölçülen genişlik ve yükseklikten farklı olabilir, ancak zorunlu değildir. Genişlik ve yüksekliği öğrenmek için
getWidth() ve
getHeight() çağrılarını kullanabilirsiniz.
Bir görünüm, boyutlarını ölçmek için dolgusunu dikkate alır. Dolgu, görünümün sol, üst, sağ ve alt bölümleri için piksel cinsinden ifade edilir.
Görünümün içeriğini belirli sayıda piksele göre dengelemek için dolgu kullanabilirsiniz. Örneğin, ikilik sol dolgu, görünümün içeriğini sol kenarın sağına iki piksel iter.
setPadding(int, int, int, int) yöntemini kullanarak dolgu ayarlayabilir ve
getPaddingLeft(),
getPaddingTop(),
getPaddingRight() ve
getPaddingBottom() yöntemini çağırarak sorgulayabilirsiniz.
Bir görünüm, dolgu tanımlayabilir olsa da kenar boşluklarını desteklemez. Ancak görünüm grupları marjları destekler. Daha fazla bilgi için
ViewGroup ve
ViewGroup.MarginLayoutParams sayfalarını inceleyin.
Boyutlar hakkında daha fazla bilgi için Boyut bölümüne bakın.
Kenar boşluklarını ve dolguyu programatik olarak ayarlamanın yanı sıra, bunları aşağıdaki örnekte gösterildiği gibi XML düzenlerinizde de ayarlayabilirsiniz:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:padding="8dp" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:paddingBottom="4dp" android:paddingEnd="8dp" android:paddingStart="8dp" android:paddingTop="4dp" android:text="Hello, I am a Button" /> </LinearLayout>
Yukarıdaki örnekte, uygulanan kenar boşluğu ve dolgu gösterilmektedir.
TextView öğesi, her yere eşit kenar boşlukları ve dolgu uygulanmış hal alır.
Button ise bunları farklı kenarlara bağımsız olarak nasıl uygulayabileceğinizi gösterir.
Sık kullanılan düzenler
ViewGroup sınıfının her bir alt sınıfı, içine yerleştirdiğiniz görünümleri benzersiz bir şekilde görüntülemenizi sağlar. En esnek düzen türü ve düzen hiyerarşinizi yüzeysel bir konumda tutmak için en iyi araçları sağlayan
ConstraintLayout düzenidir.
Aşağıda, Android platformunda yerleşik olarak bulunan yaygın düzen türlerinden bazıları verilmiştir.
Alt öğelerini tek bir yatay veya dikey satırda düzenler ve pencerenin uzunluğu ekranın uzunluğunu aşıyorsa kaydırma çubuğu oluşturur.
Web sayfalarını görüntüler.
Dinamik listeler oluşturma
Düzeninizin içeriği dinamikse veya önceden belirlenmemişse
RecyclerView veya
AdapterView alt sınıfını kullanabilirsiniz.
RecyclerView, belleği
AdapterView uygulamasından daha verimli kullandığı için genellikle daha iyi bir seçenektir.
RecyclerView ve
AdapterView ile en sık kullanılan düzenler şunlardır:
Kayan tek sütunlu bir liste görüntüler.
Sütun ve satırlardan oluşan kayan bir ızgara görüntüler.
RecyclerView, daha fazla imkan ve özel düzen yöneticisi oluşturma seçeneği sunar.
Bağdaştırıcı görünümünü verilerle doldurma
Android,
AdapterView için farklı veri türlerini alma ve görünüm oluşturmada yararlı olan birkaç
Adapter alt sınıfı sağlar. En yaygın iki adaptör şunlardır:
ArrayAdapter
- Veri kaynağınız bir diziyse bu bağdaştırıcıyı kullanın. Varsayılan olarak
ArrayAdapter, her öğede
toString()çağrısı yaparak ve içeriği
TextViewiçine yerleştirerek her dizi öğesi için bir görünüm oluşturur.
Örneğin, bir
ListViewiçinde görüntülemek istediğiniz dize diziniz varsa her dizenin ve dize dizisinin düzenini belirtmek için bir oluşturucu kullanarak yeni bir
ArrayAdapterbaşlatın:
Kotlin
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray)
Java
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);
Bu kurucu için bağımsız değişkenler şunlardır:
- Uygulamanız
Context
- Dizideki her dize için bir
TextViewiçeren düzen
- Dize dizisi
Ardından
ListViewcihazınızda
setAdapter()numaralı telefonu arayın:
Kotlin
val listView: ListView = findViewById(R.id.listview) listView.adapter = adapter
Java
ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);
Her bir öğenin görünümünü özelleştirmek isterseniz dizinizdeki nesneler için
toString()yöntemini geçersiz kılabilirsiniz.
TextViewdışında bir öğe olan her bir öğe için bir görünüm oluşturmak da (örneğin, her dizi öğesi için
ImageViewistiyorsanız)
ArrayAdaptersınıfını genişletin ve her öğe için istediğiniz görünüm türünü döndürmek amacıyla
getView()değerini geçersiz kılın.
- Uygulamanız
SimpleCursorAdapter
- Verileriniz
Cursorcihazından geldiğinde bu adaptörü kullanın.
SimpleCursorAdapterkullanırken
Cursoriçindeki her bir satır için kullanılacak bir düzen ve
Cursoriçindeki hangi sütunların istediğiniz düzen görünümlerine eklenmesini istediğinizi belirtin. Örneğin, kişilerin adları ve telefon numaralarından oluşan bir liste oluşturmak istiyorsanız her kişi için bir satır ve adlar ile numaralar için sütunlar içeren bir
Cursordöndüren bir sorgu gerçekleştirebilirsiniz. Daha sonra, her bir sonuç için düzende
Cursoröğesinden hangi sütunların bulunmasını istediğinizi belirten bir dize dizisi ve her bir sütunun yerleştirilmesi gereken ilgili görünümleri belirten bir tam sayı dizisi oluşturursunuz:
Kotlin
val fromColumns = arrayOf(ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER) val toViews = intArrayOf(R.id.display_name, R.id.phone_number)
Java
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; int[] toViews = {R.id.display_name, R.id.phone_number};
SimpleCursorAdapterörneğini örneklediğinizde, her sonuç için kullanılacak düzeni, sonuçları içeren
Cursoröğesini ve şu iki diziyi iletin:
Kotlin
val adapter = SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0) val listView = getListView() listView.adapter = adapter
Java
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); ListView listView = getListView(); listView.setAdapter(adapter);
Daha sonra
SimpleCursorAdapter, her bir
fromColumnsöğesini karşılık gelen
toViewsgörünümüne ekleyerek sağlanan düzeni kullanarak
Cursoriçindeki her satır için bir görünüm oluşturur.
Uygulamanızın kullanım süresi içinde bağdaştırıcınız tarafından okunan temel verileri değiştirirseniz
notifyDataSetChanged() numaralı telefonu arayın.
Bu işlem, ekteki görünüme verilerin değiştirildiğini bildirir ve kendini yeniler.
Tıklama etkinliklerini işleme
AdapterView.OnItemClickListener arayüzünü uygulayarak
AdapterView içinde her öğedeki tıklama etkinliklerine yanıt verebilirsiniz. Örnek:
Kotlin
listView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> // Do something in response to the click. }
Java
// Create a message handling object as an anonymous class. private OnItemClickListener messageClickedHandler = new OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id) { // Do something in response to the click. } }; listView.setOnItemClickListener(messageClickedHandler);
Ek kaynaklar
GitHub'daki Sunflower demo uygulamasında düzenlerin nasıl kullanıldığını görün.