Özel metin düzenleyiciler

Özel metin düzenleyiciler, EditText bileşenleri veya WebView metin widget'ları olmayan, ancak onCreateInputConnection() geri çağırma işlevini uygulayarak metin girişini destekleyen görünümlerdir. Bu geri çağırma, bir görünüme odaklanıldığında ve sistem, görünüm için bir InputConnection isteğinde bulunduğunda çağrılır.

Özel bir metin düzenleyiciden onCheckIsTextEditor()'e yapılan çağrı true sonucunu döndürecektir.

Özel metin düzenleyicilerde ekran kalemiyle el yazısı desteği

Android 14 (API düzeyi 34) ve sonraki sürümler, varsayılan olarak standart Android metin girişi bileşenlerinde ekran kalemi girişini destekler (Metin alanlarına ekran kalemi girişi bölümüne bakın). Ancak, özel metin giriş alanları (veya düzenleyiciler) için ek geliştirme yapılması gerekir.

Özel metin düzenleyici oluşturmak için aşağıdakileri yapın:

  1. El yazısı başlatmayı etkinleştir
  2. El yazısı desteği bildirme
  3. El yazısı hareketleri desteği (seçme, silme, ekleme vb.)
  4. IME'ye imleç konumu ve diğer konum verilerini sağlayın
  5. Ekran kalemiyle el yazısı fareyle üzerine gelme simgesini göster

El yazısı başlatmayı etkinleştir

Bir görünümde yalnızca tek bir metin düzenleyici varsa görünüm sistemi, ilgili görünüm için ekran kalemiyle el yazısını otomatik olarak başlatabilir. Aksi takdirde, görünümün kendi el yazısı başlatma mantığını uygulaması gerekir.

Otomatik el yazısı başlatma

Bir görünümde tek bir metin düzenleyici görüntüleniyorsa ve başka içerik yoksa görünümde, setAutoHandwritingEnabled(true) çağrısı yapılarak görüntüleme sisteminin otomatik el yazısı başlatma özelliği etkinleştirilebilir.

Otomatik el yazısı etkinleştirildiğinde, görünümün el yazısı sınırları içinde herhangi bir yerde başlayan ekran kalemi hareketi otomatik olarak el yazısı modunu başlatır. Giriş yöntemi düzenleyicisi (IME), ekran kalemi hareketi etkinliklerini alır ve tanınan metni kaydeder.

Ekran kalemi hareketi etkinliklerinin algılanmasına yönelik sınırları gösteren dikdörtgen içinde bir giriş alanı.
Şekil 1. EditText alanının sınırları içinde el yazısı.

Özel el yazısı başlatma

Bir görünüm, tek bir metin düzenleyiciye ek olarak birden fazla metin düzenleyici veya içerik içeriyorsa görünümün kendi el yazısı başlatma mantığını aşağıdaki gibi uygulaması gerekir:

  1. setAutoHandwritingEnabled(false) numaralı telefonu arayarak görüntüleme sisteminin otomatik el yazısı başlatmasını devre dışı bırakın.

  2. Görünümde görünen tüm metin düzenleyicilerini takip edin.

  3. dispatchTouchEvent() ürününde görünümün aldığı hareket etkinliklerini izleyin.

    • Ekran kalemi hareketi, bir metin düzenleyicinin el yazısı sınırları içinde gerçekleşirken, metin düzenleyiciye odaklanın (hâlihazırda odaklanmamışsa).

    • Düzenleyici henüz odaklanmamışsa InputMethodManager#restartInput() yöntemini çağırarak düzenleyicinin IME'sini yeni içeriklerle yeniden başlatın.

    • InputMethodManager#startStylusHandwriting() numaralı telefonu arayarak ekran kalemiyle el yazısı oturumunu başlatın.

Metin düzenleyici, kaydırılabilir bir görünümdeyse, ekran kaleminin editörün el yazısı sınırları içinde yaptığı hareketler, kaydırma olarak değil, el yazısı olarak kabul edilmelidir. Kaydırılabilir bir üst öğe görünümünün, metin düzenleyiciden gelen dokunma etkinliklerine müdahale etmesini önlemek için ViewParent#requestDisallowInterceptTouchEvent() kullanın.

API ayrıntıları

  • MotionEvent#getToolType()MotionEvent öğesinin ekran kaleminden gelip gelmediğini gösterir. Bu durumda döndürülen değer TOOL_TYPE_STYLUS veya TOOL_TYPE_ERASER olur.

  • InputMethodManager#isStylusHandwritingAvailable(): IME'nin ekran kalemiyle el yazısını destekleyip desteklemediğini belirtir. El yazısı kullanılabilirliği değişmiş olabileceğinden her InputMethodManager#startStylusHandwriting() çağrısından önce bu yöntemi çağırın.

  • InputMethodManager#startStylusHandwriting(): IME'nin el yazısı moduna girmesine neden olur. Geçerli hareketi iptal etmek için uygulamaya bir ACTION_CANCEL hareket etkinliği gönderilir. Ekran kalemi hareketi etkinlikleri artık uygulamaya gönderilmez.

    Daha önce uygulamaya gönderilmiş olan geçerli hareketin ekran kalemi hareketi etkinlikleri IME'ye yönlendirilir. IME, IME'nin takip eden tüm MotionEvent nesnelerini aldığı bir ekran kalemi mürekkep penceresi göstermek için gereklidir. IME, tanınan el yazısı metinlerini InputConnection API'lerini kullanarak kaydeder.

    IME el yazısı moduna giremiyorsa bu yöntem çağrısı bir işlem değildir.

El yazısı desteği bildirme

View#onCreateInputConnection(EditorInfo) çağrısının EditorInfo bağımsız değişkenini doldururken setStylusHandwritingEnabled() alanına metin düzenleyicinin el yazısını desteklediğini bildirin. setSupportedHandwritingGestures() ve setSupportedHandwritingGesturePreviews() ile desteklenen hareketleri tanımlayın.

El yazısı hareketlerini destekleme

IME'ler, seçmek için metni daire içine alma veya silmek için metnin üzerine yazma gibi çeşitli el yazısı hareketlerini destekleyebilir.

Şekil 2. Metni seçmek için daire içine alın.
Şekil 3. Metni silmek için karalayın.

Özel düzenleyiciler SelectGesture, DeleteGesture ve InsertGesture gibi farklı HandwritingGesture türlerini desteklemek için InputConnection#performHandwritingGesture() ve InputConnection#previewHandwritingGesture() uygulamalarını uygular.

View#onCreateInputConnection(EditorInfo) öğesinin EditorInfo bağımsız değişkenini doldururken desteklenen el yazısı hareketlerini tanımlayın (El yazısı desteği bildirme bölümüne bakın).

API ayrıntıları

  • InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer) : Hareketleri uygular. HandwritingGesture bağımsız değişkeni, hareketi metnin metnin neresinde olduğunu belirlemek için kullanabileceğiniz konum bilgilerini içerir. Örneğin, SelectGesture seçilen metin aralığını belirten bir RectF nesnesi, InsertGesture ise metnin ekleneceği metin ofsetini belirten bir PointF nesnesi sağlar.

    İşlemin sonucunu geri göndermek için Executor ve IntConsumer parametrelerini kullanın. Hem yürütücü hem de tüketici bağımsız değişkenleri sağlandığında IntConsumer#accept() çağrısı yapmak için yürütücüyü kullanın. Örneğin:

    
    executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
    
    
  • HandwritingGesture#getFallbackText(): El yazısı hareketi alanının altında geçerli bir metin yoksa IME'nin imleç konumunda kaydettiği yedek metni sağlar.

    Bazen IME, ekran kalemi hareketinin bir hareket işlemi mi yapmak yoksa el yazısıyla metin yazmak mı olduğunu belirleyemeyebilir. Özel metin düzenleyici, hareket konumunda kullanıcının niyetini belirlemekten ve uygun işlemi yapmaktan (bağlama göre) sorumludur.

    Örneğin, IME kullanıcının boşluk ekleme hareketi yapmak için aşağı doğru bir düzeltme işareti ⋁ mi yoksa "v" harfini el yazısıyla yazmak mı istediğini belirleyemiyorsa IME yedek metni "v" içeren bir InsertGesture gönderebilir.

    Düzenleyicinin ilk olarak boşluk ekleme hareketini gerçekleştirmesi gerekir. Hareket gerçekleştirilemezse (örneğin, belirtilen konumda metin yoksa) düzenleyici, imleç konumuna "v" harfini eklemeye devam etmelidir.

  • InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal): Devam eden bir hareketi önizler. Örneğin, kullanıcı bir metnin etrafına daire çizmeye başladığında, sonuçta elde edilen seçimin canlı bir önizlemesi gösterilebilir ve kullanıcı çizime devam ettikçe sürekli olarak güncellenebilir. Yalnızca belirli hareket türleri önizlenebilir (bkz. PreviewableHandwritingGesture).

    CancellationSignal parametresi, önizlemeyi iptal etmek için IME tarafından kullanılabilir. Önizlemeyi engelleyen başka etkinlikler varsa (örneğin, metin programatik olarak değiştirilirse veya yeni InputConnection komutları ortaya çıkarsa) özel düzenleyici, önizlemeyi iptal edebilir.

    Önizleme hareketleri yalnızca görüntüleme amaçlıdır ve düzenleyicinin durumunu değiştirmez. Örneğin, SelectGesture önizlemesinde düzenleyicinin mevcut seçim aralığı gizlenir ve hareket önizleme aralığı vurgulanır. Ancak önizleme iptal edildiğinde düzenleyicinin önceki seçim aralığını geri yüklemesi gerekir.

İmleç konumu ve diğer konum verilerini sağlama

El yazısı modunda IME, InputConnection#requestCursorUpdates() kullanarak imleç konumu ve diğer konum verilerini isteyebilir. Özel düzenleyici, InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo) çağrısıyla yanıt verir. CursorAnchorInfo'teki ekran kalemiyle el yazısıyla ilgili veriler aşağıdaki CursorAnchorInfo.Builder yöntemleriyle sağlanır:

  • setInsertionMarkerLocation() - İmlecin konumunu ayarlar. IME, el yazısı mürekkebini imlecin konumuna getirmek için bu değeri kullanır.
  • setEditorBoundsInfo() : Düzenleyicinin sınırlarını ve el yazısı sınırlarını belirler. IME, IME'nin el yazısı araç çubuğunu ekrana yerleştirmek için bu verileri kullanır.
  • addVisibleLineBounds(): Düzenleyicinin görünür (veya kısmen görünür olan) tüm metin satırlarının sınırlarını belirler. IME, el yazısı hareketlerini tanımada doğruluğu artırmak için çizgi sınırlarını kullanır.
  • setTextAppearanceInfo(): Metin görünümünü, metin giriş alanından türetilen bilgilerle ayarlar. IME, el yazısı mürekkebinin stilini belirlemek için bu bilgileri kullanır.

Ekran kalemiyle el yazısı fareyle üzerine gelme simgesini göster

Ekran kalemi, özel metin düzenleyicinizin el yazısı sınırlarının üzerine geldiğinde ve seçilen IME, ekran kalemiyle el yazısını destekliyorsa (InputMethodManager#isStylusHandwritingAvailable()) ekran kalemiyle el yazısı fareyle üzerine gelme simgesini görüntüleyin.

Ekran kalemiyle el yazısının üzerine gelme simgesi almak için View#onResolvePointerIcon() değerini geçersiz kılın. Geçersiz kılmada, sistemin ekran kalemiyle el yazısı fareyle üzerine gelme simgesine erişmek için PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING) çağrısı yapın.

Ek kaynaklar