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,
View
sı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,
View
veViewGroup
nesneleri 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.
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:
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
AdapterView
ListView
veya GridView
gibi bir AdapterView
örneğini, harici bir kaynaktan veri alan ve her bir View
girişini temsil eden Adapter
öğesine bağlayarak doldurabilirsiniz.
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 öğedetoString()
çağrısı yaparak ve içeriğiTextView
içine yerleştirerek her dizi öğesi için bir görünüm oluşturur.Örneğin, bir
ListView
iç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 birArrayAdapter
baş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
TextView
içeren düzen - Dize dizisi
Ardından
ListView
cihazınızdasetAdapter()
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.TextView
dışında bir öğe olan her bir öğe için bir görünüm oluşturmak da (örneğin, her dizi öğesi içinImageView
istiyorsanız)ArrayAdapter
sınıfını genişletin ve her öğe için istediğiniz görünüm türünü döndürmek amacıylagetView()
değerini geçersiz kılın. - Uygulamanız
SimpleCursorAdapter
- Verileriniz
Cursor
cihazından geldiğinde bu adaptörü kullanın.SimpleCursorAdapter
kullanırkenCursor
içindeki her bir satır için kullanılacak bir düzen veCursor
iç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 birCursor
döndüren bir sorgu gerçekleştirebilirsiniz. Daha sonra, her bir sonuç için düzendeCursor
öğ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çerenCursor
öğ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 birfromColumns
öğesini karşılık gelentoViews
görünümüne ekleyerek sağlanan düzeni kullanarakCursor
iç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.