Görünümlerdeki Düzenler

Oluşturma yöntemini deneyin
Jetpack Compose, Android için önerilen kullanıcı arayüzü araç setidir. Compose'da düzenlerle çalışma hakkında bilgi edinin.

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.

Şekil 1. Bir kullanıcı arayüzü düzenini tanımlayan görünüm hiyerarşisini gösteren görsel.

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 ve ViewGroup 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:

  1. 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"/>
    
  2. 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.

Şekil 2. Her görünümle ilişkilendirilmiş düzen parametreleriyle görünüm hiyerarşisinin görselleştirilmesi.

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.

Doğrusal düzen oluşturma

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 Görünümü'nde web uygulamaları oluşturma

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:

Liste

Kayan tek sütunlu bir liste görüntüler.

Izgara

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

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 öğede toString() çağrısı yaparak ve içeriği TextView 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 bir ArrayAdapter 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ı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. 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çin ImageView 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ıyla getView() değerini geçersiz kılın.

SimpleCursorAdapter
Verileriniz Cursor cihazından geldiğinde bu adaptörü kullanın. SimpleCursorAdapter kullanırken Cursor içindeki her bir satır için kullanılacak bir düzen ve Cursor 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 bir Cursor dö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 toViews görünümüne ekleyerek sağlanan düzeni kullanarak Cursor 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.