Giriş yöntemi oluşturma

Giriş yöntemi düzenleyicisi (IME), kullanıcıların metin girmesini sağlayan bir kullanıcı denetimidir. Android, uygulamaların kullanıcılara dokunmatik klavye veya konuşma girişi gibi alternatif giriş yöntemleri sağlamasına olanak tanıyan genişletilebilir bir giriş yöntemi çerçevesi sağlar. Kullanıcı, IME'leri yükledikten sonra sistem ayarlarından birini seçip tüm sistemde kullanabilir. Aynı anda yalnızca bir IME etkinleştirilebilir.

Android sistemine IME eklemek için InputMethodService sınıfını genişleten bir Android uygulaması oluşturun. Buna ek olarak, genellikle seçenekleri IME hizmetine ileten bir "ayarlar" etkinliği oluşturursunuz. Sistem ayarlarının bir parçası olarak gösterilen bir ayarlar kullanıcı arayüzü de tanımlayabilirsiniz.

Bu sayfada aşağıdaki konular ele alınmaktadır:

IME'lerle çalışmadıysanız öncelikle Ekranda Giriş Yöntemleri başlıklı tanıtım makalesini okuyun.

IME yaşam döngüsü

Aşağıdaki şemada bir IME'nin yaşam döngüsü açıklanmaktadır:

IME'nin yaşam döngüsünü gösteren resim.
Şekil 1. IME'nin yaşam döngüsü.

Aşağıdaki bölümlerde, bu yaşam döngüsünü takip eden bir IME ile ilişkilendirilmiş kullanıcı arayüzünün ve kodun nasıl uygulanacağı açıklanmaktadır.

Manifest'te IME bileşenlerini bildirme

Android sisteminde IME, özel bir IME hizmeti içeren bir Android uygulamasıdır. Uygulamanın manifest dosyası; hizmeti beyan etmeli, gerekli izinleri istemeli, action.view.InputMethod işlemiyle eşleşen bir amaç filtresi sağlamalı ve IME'nin özelliklerini tanımlayan meta veriler sağlamalıdır. Buna ek olarak, kullanıcının IME'nin davranışını değiştirebilmesini sağlayan bir ayarlar arayüzü sağlamak için Sistem Ayarları'ndan başlatılabilecek bir "ayarlar" etkinliği tanımlayabilirsiniz.

Aşağıdaki snippet'te bir IME hizmeti tanımlanmaktadır. Hizmetin IME'yi sisteme bağlamasına izin vermek için BIND_INPUT_METHOD izni ister, android.view.InputMethod işlemiyle eşleşen bir amaç filtresi oluşturur ve IME için meta verileri tanımlar:

<!-- Declares the input method service. -->
<service android:name="FastInputIME"
    android:label="@string/fast_input_label"
    android:permission="android.permission.BIND_INPUT_METHOD">
    <intent-filter>
        <action android:name="android.view.InputMethod" />
    </intent-filter>
    <meta-data android:name="android.view.im"
               android:resource="@xml/method" />
</service>

Sonraki snippet, IME'ye ilişkin ayar etkinliğini tanımlar. Bu etkinlikte, ACTION_MAIN için bu etkinliğin IME uygulaması için ana giriş noktası olduğunu belirten bir amaç filtresi bulunur:

<!-- Optional: an activity for controlling the IME settings. -->
<activity android:name="FastInputIMESettings"
    android:label="@string/fast_input_settings">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
    </intent-filter>
</activity>

IME'nin ayarlarına doğrudan kullanıcı arayüzünden erişim de sağlayabilirsiniz.

Giriş yöntemi API'si

IME'lere özel sınıflar android.inputmethodservice ve android.view.inputmethod paketlerinde yer almaktadır. KeyEvent sınıfı, klavye karakterlerini işlemek için önemlidir.

IME'nin merkezi bölümü, bir hizmet bileşenidir (InputMethodService bölümünü genişleten bir sınıf). Bu sınıfta, normal hizmet yaşam döngüsünün uygulanmasının yanı sıra IME'nizin kullanıcı arayüzünü sağlamak, kullanıcı girişini yönetmek ve metni odaklanılan alana iletmek için geri çağırmalar bulunur. Varsayılan olarak InputMethodService sınıfı, IME'nin durumunu ve görünürlüğünü yönetmek ve mevcut giriş alanıyla iletişim kurmak için en fazla uygulamayı sağlar.

Aşağıdaki sınıflar da önemlidir:

BaseInputConnection
InputMethod bağlantısından girişini alan uygulamaya giden iletişim kanalını tanımlar. İmleci kullanarak metin okumak, metin kutusuna metin kaydetmek ve ham önemli etkinlikleri uygulamaya göndermek için bu API'yi kullanırsınız. Uygulamalar, InputConnection temel arayüzünü uygulamak yerine bu sınıfı genişletmelidir.
KeyboardView
Klavye oluşturan ve kullanıcı girişi etkinliklerine yanıt veren bir View uzantısı. Klavye düzeni, XML dosyasında tanımlayabileceğiniz bir Keyboard örneği tarafından belirtilir.

Giriş yöntemi kullanıcı arayüzünü tasarlama

IME için iki temel görsel öğe vardır: giriş görünümü ve adaylar görünümü. Yalnızca tasarladığınız giriş yöntemiyle alakalı öğeleri uygulamanız gerekir.

Giriş görünümü

Giriş görünümü, kullanıcının tuş tıklaması, el yazısı veya hareket biçiminde metin girdiği kullanıcı arayüzüdür. IME ilk kez görüntülendiğinde sistem, onCreateInputView() geri çağırmasını çağırır. Bu yöntemi uygularken IME penceresinde görüntülemek istediğiniz düzeni oluşturun ve bu düzeni sisteme döndürün. Aşağıdaki snippet'te onCreateInputView() yönteminin uygulanmasına dair bir örnek gösterilmektedir:

Kotlin

override fun onCreateInputView(): View {
    return layoutInflater.inflate(R.layout.input, null).apply {
        if (this is MyKeyboardView) {
            setOnKeyboardActionListener(this@MyInputMethod)
            keyboard = latinKeyboard
        }
    }
}

Java

@Override
public View onCreateInputView() {
    MyKeyboardView inputView =
        (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null);

    inputView.setOnKeyboardActionListener(this);
    inputView.setKeyboard(latinKeyboard);

    return inputView;
}

Bu örnekte MyKeyboardView, Keyboard oluşturan özel bir KeyboardView uygulamasının örneğidir.

Aday görünümü

Aday görünümü, IME'nin kullanıcının seçebileceği olası kelime düzeltmelerini veya önerileri görüntülediği kullanıcı arayüzüdür. IME yaşam döngüsünde sistem, adaylar görünümünü göstermeye hazır olduğunda onCreateCandidatesView() çağrısını yapar. Bu yöntemi uygulamanızda, kelime önerileri gösteren bir düzen veya hiçbir şey göstermek istemiyorsanız null değerini döndürün. Varsayılan davranış boş yanıttır. Dolayısıyla, öneride bulunmazsanız bu seçeneği uygulamanız gerekmez.

Kullanıcı arayüzü tasarımında dikkat edilmesi gereken noktalar

Bu bölümde, IME'ler için kullanıcı arayüzü tasarımında dikkat edilmesi gereken bazı noktalar açıklanmaktadır.

Birden çok ekran boyutunu yönetin

IME'nizin kullanıcı arayüzünün farklı ekran boyutları için ölçeklendirilebilmesi ve hem yatay hem de dikey yönleri işleyebilmesi gerekir. Tam ekran olmayan IME modunda, uygulamanın metin alanını ve ilgili bağlamları göstermesi için yeterli alan bırakarak IME ekranın yarısından fazlasını kaplamamalıdır. Tam ekran IME modunda bu bir sorun değildir.

Farklı giriş türlerini işleme

Android metin alanları serbest biçimli metin, sayılar, URL'ler, e-posta adresleri ve arama dizeleri gibi belirli bir giriş türü ayarlamanıza olanak tanır. Yeni bir IME uygularken her alanın giriş türünü tespit edin ve ilgili arayüzü sağlayın. Ancak kullanıcının giriş türü için geçerli bir metin girip girmediğini kontrol etmek üzere IME'nizi ayarlamanız gerekmez. Bu, metin alanının sahibi olan uygulamanın sorumluluğudur.

Örneğin, Latince IME'nin Android platformu metin girişi için sağladığı arayüz aşağıdaki gibidir:

Latince IME&#39;de metin girişini gösteren bir resim
Şekil 2. Latince IME metin girişi.

Latince IME'nin Android platformu sayısal giriş için sağladığı arayüz şu şekildedir:

Latince IME&#39;de sayısal bir girişi gösteren resim
Şekil 3. Latince IME sayısal giriş.

Bir giriş alanına odaklanıldığında ve IME'niz başlatıldığında sistem onStartInputView() yöntemini çağırarak giriş türü ve metin alanının diğer özellikleri hakkında ayrıntıları içeren bir EditorInfo nesnesini iletir. Bu nesnedeki inputType alanı, metin alanının giriş türünü içerir.

inputType alanı, çeşitli giriş türü ayarları için bit kalıpları içeren bir int alanıdır. Metin alanının giriş türünü test etmek için, alanı aşağıdaki gibi sabit TYPE_MASK_CLASS ile maskeleyin:

Kotlin

inputType and InputType.TYPE_MASK_CLASS

Java

inputType & InputType.TYPE_MASK_CLASS

Giriş türü bit kalıbı, aşağıdakileri de içeren birkaç değerden birine sahip olabilir:

TYPE_CLASS_NUMBER
Sayı girmek için kullanılan bir metin alanı. Şekil 3'te gösterildiği gibi Latin IME, bu tür alanlar için bir sayısal tuş takımı görüntüler.
TYPE_CLASS_DATETIME
Tarih ve saat girmek için bir metin alanı.
TYPE_CLASS_PHONE
Telefon numaralarını girmek için kullanılan bir metin alanı.
TYPE_CLASS_TEXT
Desteklenen karakterleri girebileceğiniz bir metin alanı.

Bu sabit değerler, InputType referans dokümanlarında daha ayrıntılı olarak açıklanmıştır.

inputType alanı, metin alanı türünün bir varyantını gösteren diğer bitleri içerebilir. Örneğin:

TYPE_TEXT_VARIATION_PASSWORD
Şifre girmek için kullanılan bir TYPE_CLASS_TEXT varyantı. Giriş yöntemi, gerçek metin yerine dingbat'ları görüntüler.
TYPE_TEXT_VARIATION_URI
Web URL'leri ve diğer Tekdüzen Kaynak Tanımlayıcıları (URI'ler) girmek için kullanılan bir TYPE_CLASS_TEXT varyantı.
TYPE_TEXT_FLAG_AUTO_COMPLETE
Uygulamanın bir sözlükten, aramadan veya başka bir hizmetten otomatik olarak tamamladığı metni girmek için kullanılan bir TYPE_CLASS_TEXT varyantı.

Bu varyantları test ederken inputType değerini uygun sabit değerle maskeleyin. Kullanılabilir maske sabitleri, InputType referans dokümanlarında listelenmiştir.

Uygulamaya metin gönder

Kullanıcı, IME'nizle metin girerken, tek tek önemli etkinlikler göndererek veya uygulamanın metin alanında imlecin etrafındaki metni düzenleyerek uygulamaya metin gönderebilirsiniz. Her iki durumda da metni göndermek için bir InputConnection örneği kullanın. Bu örneği almak için InputMethodService.getCurrentInputConnection() numaralı telefonu arayın.

İmlecin etrafındaki metni düzenleme

Mevcut metni düzenlerken BaseInputConnection içindeki bazı faydalı yöntemler şunlardır:

getTextBeforeCursor()
İmleç konumundan önce istenen karakter sayısını içeren bir CharSequence döndürür.
getTextAfterCursor()
İmleç konumundan sonra istenen karakter sayısını içeren bir CharSequence döndürür.
deleteSurroundingText()
İmleç konumundan önce ve sonra belirtilen sayıda karakteri siler.
commitText()
Metin alanına bir CharSequence işlemi uygular ve yeni bir imleç konumu ayarlar.

Örneğin, aşağıdaki snippet'te imlecin solundaki dört karakterin "Merhaba!" metniyle nasıl değiştirileceği gösterilmektedir:

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.deleteSurroundingText(4, 0)
    ic.commitText("Hello", 1)
    ic.commitText("!", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.deleteSurroundingText(4, 0);
ic.commitText("Hello", 1);
ic.commitText("!", 1);

Kaydetmeden önce metin oluşturmayı destekleyin

IME'niz metni tahmin ediyor veya bir glif ya da kelime oluşturmak için birden çok adım gerektiriyorsa kullanıcı kelimeyi işleyene kadar metin alanında ilerleme durumunu gösterebilir ve ardından kısmi besteyi tamamlanan metinle değiştirebilirsiniz. Metni setComposingText() hizmetine ilettiğinizde span ekleyerek metne özel işlem yapabilirsiniz.

Aşağıdaki snippet'te, metin alanında ilerlemenin nasıl gösterileceği gösterilmektedir:

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.setComposingText("Composi", 1)
    ic.setComposingText("Composin", 1)
    ic.commitText("Composing ", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
ic.setComposingText("Composin", 1);
ic.commitText("Composing ", 1);

Donanım anahtarı etkinliklerine müdahale et

Giriş yöntemi penceresinde belirli bir odak noktası olmasa da donanım önce önemli etkinliklerini alır ve bunları tüketebilir veya uygulamaya yönlendirebilir. Örneğin, beste sırasında aday seçimi için kullanıcı arayüzünüzde gezinmek üzere yön tuşlarını kullanmak isteyebilirsiniz. Giriş yöntemi penceresinden gelen iletişim kutularını kapatmak için geri tuşunu da yakalamak isteyebilirsiniz.

Donanım anahtarlarına müdahale etmek için onKeyDown() ve onKeyUp() değerlerini geçersiz kılın.

Kendinizi kullanmak istemediğiniz anahtarlar için super() yöntemini çağırın.

IME alt türü oluşturma

Alt türler, IME'nin, IME tarafından desteklenen birden fazla giriş modunu ve dili göstermesini sağlar. Bir alt tür, aşağıdakileri temsil edebilir:

  • en_US veya fr_FR gibi bir yerel ayar
  • Ses, klavye veya el yazısı gibi bir giriş modu
  • 10 tuş veya QWERTY klavye düzenleri gibi IME'ye özel diğer giriş stilleri, formlar ya da özellikler

Mod, "klavye" veya "ses" gibi herhangi bir metin olabilir. Bir alt tür, bunların bir kombinasyonunu da gösterebilir.

Alt tür bilgileri, bildirim çubuğundan ulaşabileceğiniz IME değiştirici iletişim kutusu ve IME ayarları için kullanılır. Bu bilgiler aynı zamanda çerçevenin doğrudan IME'nin belirli bir alt türünü göstermesini de sağlar. IME oluştururken alt tür olanağını kullanın. Bu özellik, kullanıcının farklı IME dillerini ve modlarını tanımlamasına ve bunlar arasında geçiş yapmasına yardımcı olur.

<subtype> öğesini kullanarak giriş yönteminin XML kaynak dosyalarından birinde alt türleri tanımlayın. Aşağıdaki kod snippet'i iki alt tür içeren bir IME'yi tanımlar: ABD İngilizcesi yerel ayarı için bir klavye alt türü ve Fransa için Fransızca dil ayarı için başka bir klavye alt türü:

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
        android:settingsActivity="com.example.softkeyboard.Settings"
        android:icon="@drawable/ime_icon">
    <subtype android:name="@string/display_name_english_keyboard_ime"
            android:icon="@drawable/subtype_icon_english_keyboard_ime"
            android:languageTag="en-US"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="somePrivateOption=true" />
    <subtype android:name="@string/display_name_french_keyboard_ime"
            android:icon="@drawable/subtype_icon_french_keyboard_ime"
            android:languageTag="fr-FR"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="someVariable=30,someInternalOption=false" />
    <subtype android:name="@string/display_name_german_keyboard_ime" ... />
</input-method>

Alt türlerinizin kullanıcı arayüzünde doğru şekilde etiketlendiğinden emin olmak amacıyla alt türün yerel ayar etiketiyle aynı olan bir alt tür etiketi almak için "%s" öğesini kullanın. Bu, sonraki iki kod snippet'inde gösterilmiştir. İlk snippet, giriş yönteminin XML dosyasının bir kısmını gösterir:

<subtype
    android:label="@string/label_subtype_generic"
    android:imeSubtypeLocale="en_US"
    android:icon="@drawable/icon_en_us"
    android:imeSubtypeMode="keyboard" />

Sonraki snippet, IME'nin strings.xml dosyasının bir parçasıdır. Giriş yöntemi kullanıcı arayüzü tanımının alt türün etiketini ayarlamak için kullandığı label_subtype_generic dize kaynağı şu şekilde tanımlanır:

<string name="label_subtype_generic">%s</string>

Bu ayar, alt türün görünen adının yerel ayarla eşleşmesine neden olur. Örneğin, herhangi bir İngilizce yerel ayarda görünen ad "Türkçe (ABD)" şeklindedir.

Bildirim çubuğundan IME alt türlerini seçin

Android sistemi, tüm IME'ler tarafından sunulan tüm alt türleri yönetir. IME alt türleri, ait oldukları IME'nin modları olarak değerlendirilir. Kullanıcı, bildirim çubuğundan veya Ayarlar uygulamasından, aşağıdaki şekilde gösterildiği gibi mevcut IME alt türlerinin bulunduğu bir menüye gidebilir:

Diller ve giriş Sistem menüsünü gösteren resim
Şekil 4. Diller ve giriş sistem menüsü.

Sistem Ayarları'ndan IME alt türlerini seçin

Kullanıcı, alt türlerin nasıl kullanıldığını sistem ayarlarındaki Dil ve giriş ayarları panelinden de kontrol edebilir:

Diller seçim menüsünü gösteren resim
Şekil 5. Diller sistem menüsü

IME alt türleri arasında geçiş yapma

Klavyedeki dünya şeklindeki dil simgesi gibi bir geçiş tuşu sağlayarak kullanıcıların IME alt türleri arasında kolayca geçiş yapmasını sağlayabilirsiniz. Bu, klavyenin kullanılabilirliğini artırır ve kullanıcı için kolaylık sağlar. Bu geçişi etkinleştirmek için aşağıdaki adımları uygulayın:

  1. Giriş yönteminin XML kaynak dosyalarında supportsSwitchingToNextInputMethod = "true" tanımlayın. Beyanınız, şu kod snippet'ine benzer olmalıdır:
    <input-method xmlns:android="http://schemas.android.com/apk/res/android"
            android:settingsActivity="com.example.softkeyboard.Settings"
            android:icon="@drawable/ime_icon"
            android:supportsSwitchingToNextInputMethod="true">
    
  2. shouldOfferSwitchingToNextInputMethod() yöntemini çağırın.
  3. Yöntem true (doğru) değerini döndürürse bir geçiş anahtarı görüntüleyin.
  4. Kullanıcı değiştirme anahtarına dokunduğunda switchToNextInputMethod() yöntemini çağırarak "false" değerini iletin. Yanlış değeri, ait oldukları IME'den bağımsız olarak sisteme, tüm alt türlere eşit şekilde davranmasını söyler. Doğru değerini belirtmek için sistemin mevcut IME'deki alt türler arasında geçiş yapması gerekir.

IME ile ilgili dikkat edilmesi gereken genel noktalar

IME'nizi uygularken göz önünde bulundurmanız gereken diğer noktalar şunlardır:

  • Kullanıcıların, seçenekleri doğrudan IME'nin kullanıcı arayüzünden ayarlamaları için bir yol sağlayın.
  • Cihaza birden fazla IME yüklenmiş olabileceğinden, kullanıcılara doğrudan giriş yöntemi kullanıcı arayüzünden farklı bir IME'ye geçmeleri için bir yol sağlayın.
  • IME'nin kullanıcı arayüzünü hızlı bir şekilde açın. Kullanıcıların bir metin alanına dokunduklarında IME'yi görmesi için büyük kaynakları istek üzerine önceden yükleyin veya yükleyin. Giriş yönteminin sonraki çağrıları için kaynakları ve görünümleri önbelleğe alın.
  • Uygulamaların yeterli belleği olması için giriş yöntemi penceresi gizlendikten hemen sonra büyük bellek ayırmalarını serbest bırakın. IME birkaç saniye boyunca gizlenirse kaynakları serbest bırakmak için geciken bir mesaj kullanın.
  • Kullanıcıların, IME ile ilişkili dil veya yerel ayar için mümkün olduğunca fazla karakter girebildiğinden emin olun. Kullanıcılar şifrelerde veya kullanıcı adlarında noktalama işaretleri kullanabilir. Bu nedenle, kullanıcıların şifre girebilmesi ve cihaza erişebilmesi için IME'niz birçok farklı karakter sağlamalıdır.