Android, kullanıcı arayüzünüzü oluşturmak için View
ve ViewGroup
temel düzen sınıflarına dayalı olarak gelişmiş ve güçlü, bileşene ayrılmış bir model sunar. Platformda, kullanıcı arayüzünüzü oluşturmak için kullanabileceğiniz önceden oluşturulmuş çeşitli View
ve ViewGroup
alt sınıfı (sırasıyla, widget'lar ve düzenler) bulunmaktadır.
Kullanılabilir widget'ların kısmi listesinde Button
,
TextView
,
EditText
,
ListView
,
CheckBox
,
RadioButton
,
Gallery
,
Spinner
ile daha özel amaçlı
AutoCompleteTextView
,
ImageSwitcher
ve
TextSwitcher
yer alır.
Mevcut düzenler arasında
LinearLayout
,
FrameLayout
,
RelativeLayout
ve diğerleri yer alır. Daha fazla örnek için Genel düzenler bölümüne bakın.
Önceden oluşturulmuş widget'ların veya düzenlerin hiçbiri ihtiyaçlarınızı karşılamıyorsa kendi View
alt sınıfınızı oluşturabilirsiniz. Yalnızca mevcut bir widget veya düzende küçük ayarlamalar yapmanız gerekiyorsa widget'ı ya da düzeni alt sınıflandırabilir ve yöntemlerini geçersiz kılabilirsiniz.
Kendi View
alt sınıflarınızı oluşturmak, bir ekran öğesinin görünümü ve işlevi üzerinde hassas kontrole sahip olmanızı sağlar. Özel görünümlerle sahip olduğunuz kontrol hakkında fikir vermesi için aşağıda özel görünümlerle yapabileceklerinize ilişkin bazı örnekler verilmiştir:
-
Tamamen özel oluşturulmuş bir
View
türü (örneğin, 2D grafikler kullanılarak oluşturulmuş ve analog elektronik kontrole benzeyen bir "ses kontrol" düğmesi) oluşturabilirsiniz. -
Karma kutu (pop-up listesi ve ücretsiz giriş metin alanının kombinasyonu), çift bölmeli seçici kontrolü (her birinde hangi öğenin hangi listede olduğunu yeniden atayabileceğiniz bir liste içeren sol ve sağ bölme) oluşturmak için
View
bileşen grubunu yeni bir tek bileşende birleştirebilirsiniz. -
Bir
EditText
bileşeninin ekrandaki oluşturulma şeklini geçersiz kılabilirsiniz. NotePad örnek uygulaması, bu efekti kullanarak çizgili bir not defteri sayfası oluşturur. - Tuşa basma gibi diğer etkinlikleri yakalayabilir ve bunları özel bir şekilde (örneğin, oyun için) yönetebilirsiniz.
Aşağıdaki bölümlerde, özel görünümlerin nasıl oluşturulacağı ve bunların uygulamanızda nasıl kullanılacağı açıklanmaktadır. Ayrıntılı referans bilgileri için View
sınıfına bakın.
Temel yaklaşım
Kendi View
bileşenlerinizi oluşturmak için bilmeniz gerekenlere genel bir bakışı burada bulabilirsiniz:
-
Mevcut bir
View
sınıfının veya alt sınıfının kapsamını kendi sınıfınızla genişletin. -
Üst sınıftaki yöntemlerden bazılarını geçersiz kıl.
on
ile başlayan üst sınıf yöntemleri (ör.onDraw()
,onMeasure()
veonKeyDown()
). Bu, yaşam döngüsü ve diğer işlev kancaları için geçersiz kıldığınızActivity
veyaListActivity
içindekion
etkinliklerine benzer. - Yeni uzantı sınıfınızı kullanın. İşlem tamamlandığında, temel alınan görünüm yerine yeni uzantı sınıfınızı kullanabilirsiniz.
Tamamen özelleştirilmiş bileşenler
İstediğiniz gibi görünen, tamamen özelleştirilmiş grafik bileşenler oluşturabilirsiniz. Belki eski bir analog göstergeye benzeyen grafik bir VU ölçüm cihazı veya bir karaoke makinesiyle birlikte şarkı söyleyirken zıplayan bir topun kelimeler boyunca hareket ettiği, şarkı eşliğinde söylenen bir metin görünümü isteyebilirsiniz. Nasıl birleştirdiğinizden bağımsız olarak yerleşik bileşenlerin yapamayacağı bir şey yapmak isteyebilirsiniz.
Neyse ki, uygulamanızın masaüstü iş istasyonunuzdan çok daha az güçte çalışan bir cihazda çalışması gerekebileceğini göz önünde bulundurarak, yalnızca hayal gücünüz, ekran boyutu ve mevcut işlem gücüyle sınırlı olarak, istediğiniz gibi görünen ve davranan bileşenler oluşturabilirsiniz.
Tamamen özelleştirilmiş bir bileşen oluşturmak için aşağıdakileri göz önünde bulundurun:
-
View
, genişletebileceğiniz en genel görünümdür. Bu nedenle, genellikle yeni süper bileşeninizi oluşturmak için bu görünümü genişleterek işe başlarsınız. - XML'den özellikler ve parametreler alabilen bir kurucu sağlayabilir ve VU ölçüm cihazının rengi ve aralığı ya da iğnenin genişliği ve sönümlemesi gibi kendi özelliklerinizi ve parametrelerinizi kullanabilirsiniz.
- Muhtemelen kendi etkinlik işleyicilerinizi, mülk erişimcilerinizi ve değiştiricilerinizi oluşturmanın yanı sıra bileşen sınıfınızda daha gelişmiş bir davranış oluşturmak istersiniz.
-
Neredeyse kesinlikle
onMeasure()
politikasını geçersiz kılmak istersiniz. Ayrıca, bileşenin bir şey göstermesini istiyorsanızonDraw()
öğesini geçersiz kılmanız da gerekebilir. Her ikisinin de varsayılan davranışı olsa da varsayılanonDraw()
hiçbir şey yapmaz ve varsayılanonMeasure()
her zaman 100x100'lük bir boyut ayarlar. Bu boyutu muhtemelen istemediğiniz bir gerçektir. -
Ayrıca, gerektiğinde diğer
on
yöntemlerini geçersiz kılabilirsiniz.
onDraw() ve onMeasure() öğelerini genişletin
onDraw()
yöntemi, 2D grafikler, diğer standart veya özel bileşenler, stilize edilmiş metin ya da aklınıza gelebilecek her şey dahil olmak üzere istediğiniz her şeyi uygulayabileceğiniz bir Canvas
sunar.
onMeasure()
biraz daha dahil. onMeasure()
, bileşeniniz ile kapsayıcısı arasındaki oluşturma sözleşmesinin kritik bir parçasıdır. İçerdiği parçaların ölçümlerini verimli ve doğru bir şekilde raporlamak için onMeasure()
geçersiz kılınmalıdır. Bu durum, üst öğe tarafından onMeasure()
yöntemine geçirilen sınır gereksinimleri ve hesaplandıktan sonra ölçülen genişlik ve yükseklikle setMeasuredDimension()
yöntemini çağırma şartı nedeniyle biraz daha karmaşık hale getirir. Bu yöntemi geçersiz kılınmış bir onMeasure()
yönteminden çağırmazsanız ölçüm zamanında bir istisna oluşur.
Özetle, onMeasure()
uygulaması aşağıdaki gibi görünür:
-
Geçersiz kılınan
onMeasure()
yöntemi, genişlik ve yükseklik özellikleriyle çağrılır. Bu özellikler, oluşturduğunuz genişlik ve yükseklik ölçümleriyle ilgili kısıtlamaların gereksinimleri olarak değerlendirilir.widthMeasureSpec
veheightMeasureSpec
parametrelerinin ikisi de boyutları temsil eden tam sayı kodlarıdır. Bu spesifikasyonların gerektirebileceği kısıtlama türleri için tam referansıView.onMeasure(int, int)
adresindeki referans belgelerde bulabilirsiniz. Bu referans belgelerde, ölçüm işleminin tamamı da açıklanmaktadır. -
Bileşeninizin
onMeasure()
yöntemi, bileşeni oluşturmak için gerekli olan ölçüm genişliğini ve yüksekliğini hesaplar. Geçirilen spesifikasyonların sınırları içinde kalmaya çalışmalıdır (ancak bunları aşabilir). Bu durumda ebeveyn kırpma, kaydırma, istisna yapma veyaonMeasure()
adlı çocuğa farklı ölçüm özellikleriyle tekrar denemesini isteme gibi ne yapacağını seçebilir. -
Genişlik ve yükseklik hesaplanırken, hesaplanan ölçümlerle
setMeasuredDimension(int width, int height)
yöntemini çağırın. Aksi takdirde istisna oluşur.
Çerçevenin görüntülemeler için çağırdığı diğer standart yöntemlerin bir özetini burada bulabilirsiniz:
Kategori | Yöntemler | Açıklama |
---|---|---|
içerik üretimi | Markalar | Bir kurucu biçimi, görünüm koddan oluşturulduğunda ve görünüm bir düzen dosyasından şişirildiğinde çağrılan bir formdur. İkinci form, düzen dosyasında tanımlanan özellikleri ayrıştırır ve uygular. |
|
Bir görüntülemeden sonra çağrıldı ve tüm alt öğeleri XML'den şişirildi. | |
Düzen |
|
Bu görünüm ve tüm alt öğeleri için boyut gereksinimlerini belirlemek amacıyla çağrıldı. |
|
Bu görünümün tüm alt öğelerine boyut ve konum ataması gerektiğinde çağrılır. | |
|
Bu görünümün boyutu değiştirildiğinde çağrılır. | |
Çizim |
|
Görünümün içeriğini oluşturması gerektiğinde çağrılır. |
Etkinlik işleme |
|
Tuş kapatma etkinliği gerçekleştiğinde çağrılır. |
|
Tuş etkinliği gerçekleştiğinde çağrılır. | |
|
Bir iztopu hareketi etkinliği gerçekleştiğinde çağrılır. | |
|
Dokunmatik ekran hareketi etkinliği gerçekleştiğinde çağrılır. | |
Odak |
|
Görüntünün odağı kaybolduğunda veya kaybolduğunda çağrılır. |
|
Görünümü içeren pencere odaklanmaya başladığında veya kaybolduğunda çağrılır. | |
Ekleniyor |
|
Görünüm bir pencereye eklendiğinde çağrılır. |
|
Görünüm penceresinden ayrıldığında çağrılır. | |
|
Görünümü içeren pencerenin görünürlüğü değiştirildiğinde çağrılır. |
Bileşik denetimler
Tamamen özelleştirilmiş bir bileşen oluşturmak yerine, mevcut bir kontrol grubundan oluşan yeniden kullanılabilir bir bileşeni bir araya getirmek istiyorsanız en iyi seçenek bileşik bileşen (veya birleşik kontrol) oluşturmak olabilir. Özetle bu, bir dizi atomik kontrolü veya görünümü, tek bir öğe gibi değerlendirilebilecek mantıksal bir öğe grubu altında bir araya getirir.
Örneğin, birleşik kutu, tek bir satır EditText
alanı ve yanında pop-up liste bulunan bitişik bir düğmenin kombinasyonu olabilir. Kullanıcı düğmeye dokunur ve listeden bir şey seçerse EditText
alanı doldurulur ancak kullanıcı isterse doğrudan EditText
alanına bir şey de yazabilir.
Android'de bunu yapmak için kullanabileceğiniz iki görünüm daha vardır: Spinner
ve AutoCompleteTextView
. Yine de, açılan kutu için bu konsept iyi bir örnektir.
Bir bileşik bileşen oluşturmak için aşağıdakileri yapın:
-
Activity
öğesinde olduğu gibi, içerilen bileşenleri oluşturmak için bildirim temelli (XML tabanlı) yaklaşımı kullanın veya bunları kodunuzdan programlı bir şekilde iç içe yerleştirin. Normal başlangıç noktası bir türLayout
olduğundan,Layout
uzunluğunda bir sınıf oluşturun. Birleşik kutularda yatay yönlü birLinearLayout
kullanabilirsiniz. Diğer düzenleri iç içe yerleştirebilirsiniz. Böylece bileşik bileşen rastgele bir şekilde karmaşık ve yapılandırılmış olabilir. -
Yeni sınıfın kurucusunda, üst sınıfın beklediği parametreleri alın ve bunları önce üst sınıf kurucuya geçirin. Ardından, yeni bileşeninizde kullanmak için diğer görünümleri ayarlayabilirsiniz. Burada
EditText
alanını ve pop-up listesini oluşturursunuz. Oluşturucunuzun çekip kullanabileceği XML'e kendi özelliklerinizi ve parametrelerinizi ekleyebilirsiniz. -
İsteğe bağlı olarak, içerilen görünümlerinizin oluşturabileceği etkinlikler için işleyiciler oluşturun. Bir liste seçimi yapılırsa
EditText
içeriğini güncellemek üzere liste öğesi tıklama işleyici için bir işleyici yöntemi örnek olarak verilebilir. -
İsteğe bağlı olarak, erişimciler ve değiştiricilerle kendi mülklerinizi oluşturabilirsiniz. Örneğin, başlangıçta
EditText
değerinin bileşende ayarlanmasına izin verin ve gerektiğinde içeriğini sorgulayın. -
İsteğe bağlı olarak
onDraw()
veonMeasure()
değerlerini geçersiz kılın. Düzen, muhtemelen iyi sonuç veren varsayılan davranışa sahip olduğundan bu işlem,Layout
genişletilirken genellikle gerekli değildir. -
İsteğe bağlı olarak,
onKeyDown()
gibi diğeron
yöntemlerini geçersiz kılın. Örneğin, belirli bir tuşa dokunulduğunda bir birleşik kutu pop-up listesinden belirli varsayılan değerleri seçebilirsiniz.
Özel kontrol için temel olarak Layout
kullanmanın avantajları vardır. Örneğin:
- Bir etkinlik ekranında olduğu gibi bildirim temelli XML dosyalarını kullanarak düzeni belirtebilir veya görünümleri programatik olarak oluşturup kodunuzdan düzene iç içe yerleştirebilirsiniz.
-
onDraw()
veonMeasure()
yöntemleri ile diğeron
yöntemlerinin çoğu uygun davranışa sahiptir. Bu nedenle, bunları geçersiz kılmanız gerekmez. - Rastgele karmaşık bileşik görünümleri hızlı bir şekilde oluşturabilir ve bunları tek bir bileşen gibi yeniden kullanabilirsiniz.
Mevcut görünüm türünü değiştirme
İstediğinize benzer bir bileşen varsa bu bileşeni genişletebilir ve değiştirmek istediğiniz davranışı geçersiz kılabilirsiniz. Yapacağınız tüm işlemleri tamamen özelleştirilmiş bir bileşenle yapabilirsiniz ancak View
hiyerarşisinde daha uzmanlaşmış bir sınıfla başlayarak, istediğiniz şeyi ücretsiz olarak yapan bazı davranışlar elde edebilirsiniz.
Örneğin, NotePad örnek uygulaması, Android platformunu kullanmanın birçok yönünü gösterir. Bunların arasında, çizgili not defteri oluşturmak
için bir EditText
görünümü genişletme de kullanılabilir. Bu mükemmel bir örnek değil. Buna yönelik API'ler değişebilir ama ilkeleri görebilirsiniz.
Henüz yapmadıysanız NotePad örneğini Android Studio'ya aktarın veya sağlanan bağlantıyı kullanarak kaynağa bakın. Özellikle NoteEditor.java
dosyasındaki LinedEditText
tanımını inceleyin.
Bu dosyada dikkat edilmesi gereken bazı noktalar şunlardır:
-
Tanım
Sınıf aşağıdaki satırla tanımlanır:
public static class LinedEditText extends EditText
LinedEditText
,NoteEditor
etkinliği içindeki bir iç sınıf olarak tanımlanır ancakNoteEditor
sınıfının dışındanNoteEditor.LinedEditText
olarak erişilebilir olması için herkese açıktır.Ayrıca
LinedEditText
,static
değerine sahiptir. Yani üst sınıftaki verilere erişmesine izin veren "sentetik yöntemler" oluşturmaz. Bu daNoteEditor
ile yakından ilişkili bir şey değil, ayrı bir sınıf olarak davrandığı anlamına gelir. Bu, dış sınıftan durum erişimine ihtiyaçları olmayan iç sınıfları oluşturmanın daha temiz bir yoludur. Oluşturulan sınıfı küçük tutar ve diğer sınıflardan kolayca kullanılabilmesini sağlar.LinedEditText
, bu durumda özelleştirilecek görünüm olanEditText
adlı görünümü genişletir. İşiniz bittiğinde yeni sınıf normal birEditText
görünümünün yerini alabilir. -
Sınıfı başlatma
Her zaman olduğu gibi, önce süper çağrılır. Bu, varsayılan bir kurucu değildir ancak parametreleştirilmiş bir oluşturucudur.
EditText
, bir XML düzen dosyasından şişirildiğinde bu parametrelerle oluşturulur. Dolayısıyla, kurucunun bunları alıp süper sınıf oluşturucuya da iletmesi gerekir. -
Geçersiz kılınan yöntemler
Bu örnek yalnızca
onDraw()
yöntemini geçersiz kılar, ancak kendi özel bileşenlerinizi oluştururken diğerlerini geçersiz kılmanız gerekebilir.Bu örnekte
onDraw()
yöntemini geçersiz kılmak,EditText
görünümündeki mavi çizgileri boyayabilmenizi sağlar. Tuval, geçersiz kılınanonDraw()
yöntemine geçirilir.super.onDraw()
yöntemi, yöntem sona ermeden önce çağrılır. Superclass yöntemi çağrılmalıdır. Bu durumda, eklemek istediğiniz satırları boyadıktan sonra en sonda çağırın. -
Özel bileşen
Artık özel bileşeniniz var, peki onu nasıl kullanabilirsiniz? NotePad örneğinde, özel bileşen doğrudan bildirim temelli düzenden kullanılmaktadır. Bu nedenle,
res/layout
klasöründekinote_editor.xml
öğesine bakın:<view xmlns:android="http://schemas.android.com/apk/res/android" class="com.example.android.notepad.NoteEditor$LinedEditText" android:id="@+id/note" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:padding="5dp" android:scrollbars="vertical" android:fadingEdge="vertical" android:gravity="top" android:textSize="22sp" android:capitalize="sentences" />
Özel bileşen, XML'de bir genel görünüm olarak oluşturulur ve sınıf, tam paket kullanılarak belirtilir. Tanımladığınız iç sınıfa, Java programlama dilindeki iç sınıflara referans vermenin standart bir yolu olan
NoteEditor$LinedEditText
gösterimi kullanılarak başvuruda bulunulur.Özel görünüm bileşeniniz bir iç sınıf olarak tanımlanmamışsa görünüm bileşenini XML öğe adıyla belirtip
class
özelliğini hariç tutabilirsiniz. Örneğin:<com.example.android.notepad.LinedEditText id="@+id/note" ... />
LinedEditText
sınıfının artık ayrı bir sınıf dosyası olduğuna dikkat edin. Sınıf,NoteEditor
sınıfının içine yerleştirildiğinde bu teknik işe yaramaz.Tanımdaki diğer özellik ve parametreler, özel bileşen oluşturucuya iletilen ve ardından
EditText
oluşturucuya iletilen özelliklerdir. Dolayısıyla bunlar,EditText
görünümü için kullandığınız parametrelerdir. Kendi parametrelerinizi de ekleyebilirsiniz.
Özel bileşenler oluşturmak, ihtiyacınız olduğu kadar karmaşıktır.
Daha karmaşık bir bileşen daha fazla on
yöntemini geçersiz kılıp kendi yardımcı yöntemlerini tanıtarak özelliklerini ve davranışını önemli ölçüde özelleştirebilir. Tek sınır, sizin hayal gücünüz ve
bileşenin ne yapması gerektiğidir.