Android, kullanıcı arayüzünüzü oluşturmak için temel düzen sınıflarına View ve ViewGroup dayalı, gelişmiş ve güçlü bir bileşenli model sunar. Platformda, kullanıcı arayüzünüzü oluşturmak için kullanabileceğiniz çeşitli önceden oluşturulmuş View ve ViewGroup alt sınıflar (sırasıyla widget'lar ve düzenler olarak adlandırılır) bulunur.
Kullanılabilir widget'ların kısmi listesinde Button,
TextView,
EditText,
ListView,
CheckBox,
RadioButton,
Gallery,
Spinner ve daha özel amaçlı AutoCompleteTextView,
ImageSwitcher ve TextSwitcher yer alır.
Kullanabileceğiniz düzenler arasında LinearLayout, FrameLayout, RelativeLayout ve diğerleri yer alır. Daha fazla örnek için Sık kullanılan düzenler başlıklı makaleyi inceleyin.
Önceden oluşturulmuş widget'lardan veya düzenlerden hiçbiri ihtiyaçlarınızı karşılamıyorsa kendi Viewalt sınıfınızı oluşturabilirsiniz. Mevcut bir widget'ta veya düzende yalnızca küçük ayarlamalar yapmanız gerekiyorsa widget'ı ya da düzeni alt sınıfa ayı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 kontrol sahibi olmanızı sağlar. Özel görünümlerle elde ettiğiniz kontrol hakkında fikir vermek için bu görünümlerle yapabileceklerinize dair bazı örnekleri aşağıda bulabilirsiniz:
-
Tamamen özel olarak oluşturulmuş bir
Viewtürü oluşturabilirsiniz. Örneğin, 2D grafikler kullanılarak oluşturulmuş ve analog elektronik kontrole benzeyen bir "ses kontrolü" düğmesi. -
Bir grup
Viewbileşeni yeni bir tek bileşende birleştirebilirsiniz. Örneğin, birleşik kutu (açılır liste ve serbest giriş metin alanının birleşimi), çift bölmeli seçici kontrolü (her birinde bir liste bulunan sol ve sağ bölme; hangi öğenin hangi listede olduğunu yeniden atayabilirsiniz) gibi öğeler oluşturabilirsiniz. -
Bir
EditTextbileşenin ekranda oluşturulma şeklini geçersiz kılabilirsiniz. Not Defteri örnek uygulamasında, çizgili bir not defteri sayfası oluşturmak için bu özellikten iyi bir şekilde yararlanılır. - Tuşlara basma gibi diğer etkinlikleri yakalayabilir ve bunları özel bir şekilde (ör. oyun için) işleyebilirsiniz.
Aşağıdaki bölümlerde, özel görünümlerin nasıl oluşturulacağı ve 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ış:
-
Mevcut bir
Viewsınıfını veya alt sınıfını kendi sınıfınızla genişletin. -
Üst sınıftaki bazı yöntemleri geçersiz kılın. Geçersiz kılınacak üst sınıf yöntemleri
onile başlar. Örneğin,onDraw(),onMeasure()veonKeyDown(). Bu,onveyaListActivityiçindekiActivityetkinliklerine benzer. Bu etkinlikleri yaşam döngüsü ve diğer işlevsel kancalar için geçersiz kılarsınız. - Yeni uzantı sınıfınızı kullanın. İşlem tamamlandıktan sonra, yeni uzantı sınıfınızı temel aldığı görünüm yerine kullanabilirsiniz.
Tamamen özelleştirilmiş bileşenler
Tamamen özelleştirilmiş grafik bileşenleri oluşturabilir ve bunları istediğiniz şekilde gösterebilirsiniz. Belki eski bir analog ölçere benzeyen grafik bir VU ölçer veya karaoke makinesiyle şarkı söylerken kelimeler arasında hareket eden bir topun yer aldığı, şarkı söyleme metin görünümü istiyorsunuzdur. Yerleşik bileşenleri ne kadar çok birleştirirseniz birleştirin, bu bileşenlerin yapamayacağı bir şey isteyebilirsiniz.
Neyse ki yalnızca hayal gücünüz, ekranın boyutu ve mevcut işlem gücüyle sınırlı olarak istediğiniz gibi görünen ve çalışan bileşenler oluşturabilirsiniz. Uygulamanızın masaüstü iş istasyonunuzdan önemli ölçüde daha az güce sahip bir cihazda çalışması gerekebileceğini unutmayın.
Tamamen özelleştirilmiş bir bileşen oluşturmak için aşağıdakileri göz önünde bulundurun:
-
Genişletebileceğiniz en genel görünüm
View'dir. Bu nedenle, genellikle yeni süper bileşeninizi oluşturmak için bunu genişleterek başlarsınız. - XML'den özellikler ve parametreler alabilen bir oluşturucu sağlayabilir ve VU ölçerin rengi ile aralığı veya iğnenin genişliği ve sönümlemesi gibi kendi özelliklerinizi ve parametrelerinizi kullanabilirsiniz.
- Muhtemelen kendi etkinlik dinleyicilerinizi, özellik erişimcilerinizi ve değiştiricilerinizi oluşturmak ve bileşen sınıfınızda daha karmaşık davranışlar kullanmak istersiniz.
-
onMeasure()değerini geçersiz kılmak istediğinizden neredeyse kesinlikle eminsinizdir ve bileşenin bir şeyler göstermesini istiyorsanızonDraw()değerini de geçersiz kılmanız gerekir. Her ikisi de varsayılan davranışa sahip olsa da varsayılanonDraw()hiçbir şey yapmaz ve varsayılanonMeasure()her zaman 100x100 boyutunu ayarlar. Bu da muhtemelen istemeyeceğiniz bir durumdur. -
Gerekirse diğer
onyöntemlerini de geçersiz kılabilirsiniz.
onDraw() ve onMeasure() işlevlerini genişletme
onDraw() yöntemi, istediğiniz her şeyi uygulayabileceğiniz bir Canvas sunar: 2D grafikler, diğer standart veya özel bileşenler, stilize edilmiş metin ya da aklınıza gelebilecek başka herhangi bir şey.
onMeasure() biraz daha karmaşıktır. onMeasure(), bileşeniniz ile kapsayıcısı arasındaki oluşturma sözleşmesinin kritik bir parçasıdır. onMeasure(), içerdiği parçaların ölçümlerini verimli ve doğru bir şekilde raporlamak için geçersiz kılınmalıdır. Bu durum, ebeveynin sınır koşulları (onMeasure() yöntemine aktarılır) ve genişlik ile yüksekliğin hesaplanmasının ardından setMeasuredDimension() yönteminin ölçülen genişlik ve yükseklikle çağrılması zorunluluğu nedeniyle biraz daha karmaşık hale gelir. Bu yöntemi geçersiz kılınan bir onMeasure() yönteminden çağırmazsanız ölçüm sırasında istisna oluşur.
onMeasure()'nın uygulanması genel olarak şu şekilde yapılır:
-
Geçersiz kılınan
onMeasure()yöntemi, genişlik ve yükseklik spesifikasyonlarıyla birlikte çağrılır. Bu spesifikasyonlar, oluşturduğunuz genişlik ve yükseklik ölçümlerindeki kısıtlamalar için gereklilik olarak kabul edilir.widthMeasureSpecveheightMeasureSpecparametreleri, boyutları temsil eden tam sayı kodlardır. Bu spesifikasyonların gerektirebileceği kısıtlamalarla ilgili tam referansı,View.onMeasure(int, int)bölümündeki referans belgelerinde bulabilirsiniz. Bu referans belgelerinde, ölçüm işleminin tamamı da açıklanmaktadır. -
Bileşeninizin
onMeasure()yöntemi, bileşeni oluşturmak için gereken bir ölçü genişliği ve yüksekliği hesaplar. Bu işlev, belirtilen spesifikasyonları aşabilse de bu spesifikasyonlar dahilinde kalmaya çalışmalıdır. Bu durumda üst öğe, kırpma, kaydırma, istisna oluşturma veyaonMeasure()öğesinden farklı ölçüm spesifikasyonlarıyla tekrar denemesini isteme gibi seçeneklerden birini belirleyebilir. -
Genişlik ve yükseklik hesaplandığında, hesaplanan ölçülerle
setMeasuredDimension(int width, int height)yöntemini çağırın. Bunu yapmazsanız istisna oluşur.
Çerçevenin görünümlerde çağırdığı diğer standart yöntemlerin özeti aşağıda verilmiştir:
| Kategori | Yöntemler | Açıklama |
|---|---|---|
| içerik üretimi | Markalar | Görünüm koddan oluşturulduğunda çağrılan bir oluşturucu biçimi ve görünüm bir düzen dosyasından genişletildiğinde çağrılan bir biçim vardır. İkinci form, düzen dosyasında tanımlanan özellikleri ayrıştırır ve uygular. |
|
Bir görünüm ve tüm alt öğeleri XML'den şişirildikten sonra çağrılır. | |
| Düzen | |
Bu görünüm ve tüm alt öğeleri için boyut koşullarını belirlemek üzere çağrılır. |
|
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 | |
Bir tuşa basma etkinliği gerçekleştiğinde çağrılır. |
|
Bir tuşu bırakma etkinliği gerçekleştiğinde çağrılır. | |
|
Bir trackball hareket etkinliği gerçekleştiğinde çağrılır. | |
|
Dokunmatik ekran hareket etkinliği gerçekleştiğinde çağrılır. | |
| Odak | |
Görünüm odak kazandığında veya kaybettiğinde çağrılır. |
|
Görünümü içeren pencere odak kazandığında veya odağı kaybettiğinde çağrılır. | |
| Ekleme | |
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 kontroller
Tamamen özelleştirilmiş bir bileşen oluşturmak istemiyorsanız ancak mevcut kontrollerden oluşan yeniden kullanılabilir bir bileşen oluşturmak istiyorsanız bileşik bileşen (veya bileşik kontrol) oluşturmak en iyi seçenek olabilir. Özetle, bu özellik daha atomik kontrolleri veya görünümleri tek bir şey olarak ele alınabilecek mantıksal bir öğe grubunda bir araya getirir.
Örneğin, bir birleşik kutu, tek satırlık bir EditText alan ile eklenmiş bir pop-up liste içeren bitişik bir düğmenin birleşimi olabilir. Kullanıcı düğmeye dokunup listeden bir öğe seçerse EditText alanı doldurulur. Ancak kullanıcılar isterlerse doğrudan EditText alanına da yazabilir.
Android'de bunu yapmak için kullanabileceğiniz iki görünüm daha vardır: Spinner ve AutoCompleteTextView. Bununla birlikte, birleşik kutu için bu konsept iyi bir örnek teşkil eder.
Bileşik bileşen oluşturmak için aşağıdakileri yapın:
-
Activityile olduğu gibi, kapsanan bileşenleri oluşturmak için bildirimsel (XML tabanlı) yaklaşımı kullanın veya bunları kodunuzdan programatik olarak yerleştirin. Genellikle başlangıç noktası bir türLayoutolur. Bu nedenle,Layoutöğesini genişleten bir sınıf oluşturun. Birleşik kutu söz konusu olduğunda, yatay yönlendirmeye sahip birLinearLayoutkullanabilirsiniz. İçine başka düzenler yerleştirebilirsiniz. Böylece bileşik bileşen, isteğe bağlı olarak karmaşık ve yapılandırılmış olabilir. -
Yeni sınıfın oluşturucusunda, üst sınıfın beklediği tüm parametreleri alın ve bunları önce üst sınıf oluşturucusuna iletin. Ardından, yeni bileşeninizde kullanmak üzere diğer görünümleri ayarlayabilirsiniz.
EditTextalanını ve pop-up listeyi burada oluşturursunuz. Oluşturucunuzun çekip kullanabileceği XML'ye kendi özelliklerinizi ve parametrelerinizi ekleyebilirsiniz. -
İsteğe bağlı olarak, kapsanan görünümlerinizin oluşturabileceği etkinlikler için işleyiciler oluşturun. Örneğin, liste öğesi tıklama dinleyicisi için bir dinleyici yöntemi, liste seçimi yapıldığında
EditTextiçeriğini günceller. -
İsteğe bağlı olarak, erişim yöntemleri ve değiştiricilerle kendi özelliklerinizi oluşturun. Örneğin,
EditTextdeğeri başlangıçta bileşende ayarlansın ve gerektiğinde içeriği sorgulansın. -
İsteğe bağlı olarak
onDraw()veonMeasure()değerlerini geçersiz kılın. Düzenin muhtemelen sorunsuz çalışacak varsayılan davranışı olduğundan,Layoutgenişletilirken bu genellikle gerekli değildir. -
İsteğe bağlı olarak, belirli bir tuşa dokunulduğunda birleşik kutunun pop-up listesinden belirli varsayılan değerleri seçmek için
ongibi diğeronKeyDown()yöntemlerini geçersiz kılın.
Özel denetim için temel olarak Layout kullanmanın aşağıdaki gibi avantajları vardır:
- Düzeni, etkinlik ekranında olduğu gibi bildirimli XML dosyalarını kullanarak belirtebilir veya görünümleri programatik olarak oluşturup kodunuzdaki düzene yerleştirebilirsiniz.
-
onDraw()veonMeasure()yöntemlerinin yanı sıra diğeronyöntemlerin çoğu uygun davranışa sahiptir. Bu nedenle, bunları geçersiz kılmanız gerekmez. - İstediğiniz kadar karmaşık bileşik görünümler oluşturabilir ve bunları tek bir bileşenmiş gibi yeniden kullanabilirsiniz.
Mevcut bir görünüm türünü değiştirme
İstediğiniz gibi bir bileşen varsa bu bileşeni genişletebilir ve değiştirmek istediğiniz davranışı geçersiz kılabilirsiniz. Tamamen özelleştirilmiş bir bileşenle yaptığınız her şeyi yapabilirsiniz ancak View hiyerarşisinde daha uzmanlaşmış bir sınıfla başlayarak istediğiniz davranışı ücretsiz olarak elde edebilirsiniz.
Örneğin, NotePad örnek uygulaması, Android platformunu kullanmanın birçok yönünü gösterir. Bunlardan biri, çizgili not defteri oluşturmak için EditText görünümünü genişletmektir. Bu mükemmel bir örnek değildir ve bunu yapmak için kullanılan API'ler değişebilir ancak bu örnek, temel ilkeleri gösterir.
Henüz yapmadıysanız NotePad örneğini Android Studio'ya aktarın veya sağlanan bağlantıyı kullanarak kaynağa göz atın. Özellikle LinedEditText
tanımını
NoteEditor.java
dosyasında inceleyin.
Bu dosyada dikkat etmeniz gereken bazı noktalar:
-
Tanım
Sınıf, şu satırla tanımlanır:
public static class LinedEditText extends EditTextLinedEditText,NoteEditoretkinliğinde bir iç sınıf olarak tanımlanır ancakNoteEditorsınıfının dışındanNoteEditor.LinedEditTextolarak erişilebilmesi için herkese açıktır.Ayrıca,
LinedEditText,static'dir. Yani, üst sınıftaki verilere erişmesini sağlayan "sentez yöntemleri" oluşturmaz. Bu nedenle,NoteEditorile yakından ilişkili bir şey olmaktan ziyade ayrı bir sınıf gibi davranır. Bu, dış sınıftaki duruma erişmeleri gerekmeyen iç sınıfları oluşturmanın daha temiz bir yoludur. Oluşturulan sınıfın küçük kalmasını sağlar ve diğer sınıflarda kolayca kullanılabilmesine olanak tanır.LinedEditText, bu durumda özelleştirilecek görünüm olanEditText'ü genişletir. İşlemi tamamladığınızda yeni sınıf, normalEditTextgörünümünün yerine kullanılabilir. -
Sınıf başlatma
Her zaman olduğu gibi, önce süper metot çağrılır. Bu, varsayılan bir oluşturucu değildir ancak parametreli bir oluşturucudur.
EditText, bir XML düzen dosyasından şişirildiğinde bu parametrelerle oluşturulur. Bu nedenle, oluşturucunun bunları alıp üst sınıf oluşturucusuna da iletmesi gerekir. -
Geçersiz kılınan yöntemler
Bu örnekte yalnızca
onDraw()yöntemi geçersiz kılınır. Ancak kendi özel bileşenlerinizi oluştururken diğerlerini de geçersiz kılmanız gerekebilir.Bu örnekte,
onDraw()yöntemini geçersiz kılmak,EditTextgörünüm tuvaline mavi çizgiler çizmenize olanak tanır. Tuval, geçersiz kılınanonDraw()yöntemine iletilir.super.onDraw()yöntemi, yöntemi sona ermeden önce çağrılır. Üst sınıf yöntemi çağrılmalıdır. Bu durumda, dahil etmek istediğiniz çizgileri boyadıktan sonra bu işlevi en son kullanın. -
Özel bileşen
Artık özel bileşeniniz var ancak bunu nasıl kullanabilirsiniz? Not defteri örneğinde, özel bileşen doğrudan bildirim temelli düzenden kullanıldığından
res/layoutklasö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 genel bir görünüm olarak oluşturulur ve sınıf, tam paket kullanılarak belirtilir. Tanımladığınız iç sınıf, Java programlama dilinde iç sınıflara başvurmak için standart bir yöntem olan
NoteEditor$LinedEditTextgösterimi kullanılarak referans alınır.Özel görünüm bileşeniniz iç sınıf olarak tanımlanmamışsa görünüm bileşenini XML öğe adıyla bildirebilir ve
classözelliğini hariç tutabilirsiniz. Örneğin:<com.example.android.notepad.LinedEditText id="@+id/note" ... />
LinedEditTextsınıfının artık ayrı bir sınıf dosyası olduğuna dikkat edin. Sınıf,NoteEditorsınıfının içine yerleştirildiğinde bu teknik çalışmaz.Tanımdaki diğer özellikler ve parametreler, özel bileşen oluşturucusuna aktarılan ve ardından
EditTextoluşturucusuna aktarılanlardır. Bu nedenle,EditTextgörünümü için kullandığınız parametrelerle aynıdır. Kendi parametrelerinizi de ekleyebilirsiniz.
Özel bileşenler oluşturmak, ihtiyacınız olduğu kadar karmaşık olabilir.
Daha karmaşık bir bileşen, daha fazla on yöntemi geçersiz kılabilir ve kendi yardımcı yöntemlerini sunarak özelliklerini ve davranışını önemli ölçüde özelleştirebilir. Tek sınır, hayal gücünüz ve bileşenin yapmasını istediğiniz işlemlerdir.