Metin alanlarını yapılandırma

TextField, kullanıcıların metin girmesine ve metni değiştirmesine olanak tanır. Kullanabileceğiniz iki tür metin alanı vardır: duruma dayalı metin alanları ve değere dayalı metin alanları. İçerik göstermek istediğiniz türü seçin:

TextField durumunu yönetmek için daha kapsamlı ve güvenilir bir yaklaşım sundukları için duruma dayalı metin alanları kullanmanızı öneririz. Aşağıdaki tabloda bu metin alanı türleri arasındaki farklar özetlenmiştir ve duruma dayalı metin alanlarının sunduğu temel avantajlar belirtilmiştir:

Özellik

Değere dayalı metin alanları

Eyalete dayalı metin alanları

Eyalete dayalı avantaj

Durum yönetimi

Metin alanı durumunu onValueChange geri çağırma işleviyle günceller. onValueChange tarafından bildirilen değişikliklere göre kendi eyaletinizde value'yi güncellemekten sorumlusunuz.

Metin girişi durumunu (değer, seçim, kompozisyon) yönetmek için açıkça bir TextFieldState nesnesi kullanır. Bu durum hatırlanabilir ve paylaşılabilir.

  • onValueChange geri çağırma işlevi kaldırıldı. Bu, senkronize olmayan davranışlar eklemenizi engeller.
  • Durum, yeniden derleme, yapılandırma ve işlem sonlandırma işlemlerinden etkilenmez.

Görsel dönüşüm

Gösterilen metnin görünümünü değiştirmek için VisualTransformation kullanır. Bu işlem genellikle hem giriş hem de çıkış biçimlendirmesini tek bir adımda gerçekleştirir.

Kullanıcının girişini duruma bağlanmadan önce değiştirmek için InputTransformation'ü, temel durum verilerini değiştirmeden metin alanı içeriğini biçimlendirmek için OutputTransformation'ü kullanır.

  • Artık OutputTransformation ile orijinal ham metin ile dönüştürülmüş metin arasındaki ofset eşlemesini sağlamanız gerekmez.

Satır sınırları

Satır sayısını kontrol etmek için singleLine: Boolean, maxLines: Int ve minLines: Int değerlerini kabul eder.

Metin alanının kaplayabildiği minimum ve maksimum satır sayısını yapılandırmak için lineLimits: TextFieldLineLimits kullanır.

  • TextFieldLineLimits türüne sahip bir lineLimits parametresi sağlayarak satır sınırlarını yapılandırırken belirsizliği ortadan kaldırır.

Güvenli metin alanı

Yok

SecureTextField, şifre alanı yazmak için durum tabanlı metin alanlarının üzerine inşa edilmiş bir bileşendir.

  • Arka planda güvenlik için optimizasyon yapmanıza olanak tanır ve textObfuscationMode ile önceden tanımlanmış bir kullanıcı arayüzü sunar.

Bu sayfada, TextField'ü nasıl uygulayabileceğiniz, TextField girişini nasıl biçimlendirebileceğiniz ve klavye seçenekleri ile kullanıcı girişini görsel olarak dönüştürme gibi diğer TextField seçeneklerini nasıl yapılandırabileceğiniz açıklanmaktadır.

TextField uygulamasını seçin

TextField'ün iki düzeyde uygulanması vardır:

  1. TextField, Materyal Tasarım uygulamasıdır. Materyal Tasarım yönergelerine uygun olduğu için bu uygulamayı seçmenizi öneririz:
  2. BasicTextField, kullanıcıların donanım veya yazılım klavyesi aracılığıyla metni düzenlemesine olanak tanır ancak ipucu veya yer tutucu gibi süslemeler sağlamaz.

TextField(
    state = rememberTextFieldState(initialText = "Hello"),
    label = { Text("Label") }
)

Kelimeyi içeren düzenlenebilir bir metin alanı

OutlinedTextField(
    state = rememberTextFieldState(),
    label = { Text("Label") }
)

Mor kenarlıklı ve etiketli düzenlenebilir bir metin alanı.

Stil TextField

TextField ve BasicTextField, özelleştirme için birçok ortak parametreyi paylaşır. TextField için tam listeyi TextField kaynak kodunda bulabilirsiniz. Aşağıda, yararlı parametrelerden bazılarının kapsamlı olmayan bir listesi verilmiştir:

  • textStyle
  • lineLimits

TextField(
    state = rememberTextFieldState("Hello\nWorld\nInvisible"),
    lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2),
    placeholder = { Text("") },
    textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
    label = { Text("Enter text") },
    modifier = Modifier.padding(20.dp)
)

İki düzenlenebilir satır ve etiket içeren çok satırlı bir TextField

Tasarımınız için TextField veya OutlinedTextField malzemesi gerektiğinde BasicTextField yerine TextField kullanmanızı öneririz. Ancak BasicTextField, malzeme spesifikasyonundaki süslemelere ihtiyaç duymayan tasarımlar oluştururken kullanılmalıdır.

Satır sınırlarını yapılandırma

TextField bileşenleri tek bir eksende kaydırmayı destekler. Kaydırma davranışı lineLimits parametresi tarafından belirlenir. Tek satırlık kaydırma için yapılandırılmış TextField'lar yatay olarak kayarken çok satırlık TextField'lar dikey olarak kayar.

TextField için uygun satır yapılandırmasını seçmek üzere TextFieldLineLimits'ü kullanın:

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine
)

Metin içeren tek satırlık bir metin alanı

SingleLine yapılandırması aşağıdaki özelliklere sahiptir:

  • Metin hiçbir zaman sarmalanmaz ve yeni satırlara izin verilmez.
  • TextField her zaman sabit yüksekliğe sahiptir.
  • Metin taşarsa yatay olarak kayar.

TextField(
    state = rememberTextFieldState("Hello\nWorld\nHello\nWorld"),
    lineLimits = TextFieldLineLimits.MultiLine(1, 4)
)

Metin içeren çok satırlı metin alanı

MultiLine yapılandırması aşağıdaki özelliklere sahiptir:

  • İki parametreyi kabul eder: minHeightInLines ve maxHeightInLines.
  • Metin alanı en az minHeightInLines yüksekliğindedir.
  • Metin taşarsa sarmalanır.
  • Metin için daha fazla satır gerekiyorsa alan maxHeightInLines yüksekliğinde olana kadar büyür ve dikey olarak kaydırılır.

Brush API ile stil girişi

TextField'nizde daha gelişmiş bir stil oluşturmak için Brush API'yi kullanabilirsiniz. Aşağıdaki bölümde, TextField girişine renkli bir degrade eklemek için Fırça'yı nasıl kullanabileceğiniz açıklanmaktadır.

Metne stil uygulamak için Brush API'yi kullanma hakkında daha fazla bilgi edinmek isterseniz Brush API ile gelişmiş stillendirmeyi etkinleştirme başlıklı makaleyi inceleyin.

TextStyle kullanarak renkli degradeler uygulama

Bir TextField içinde yazarken renkli degrade uygulamak için tercih ettiğiniz fırçayı TextField için TextStyle olarak ayarlayın. Bu örnekte, TextField alanına metin girilirken gökkuşağı degrade efektini görüntülemek için linearGradient içeren yerleşik bir fırça kullanıyoruz.

val brush = remember {
    Brush.linearGradient(
        colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta)
    )
}
TextField(
    state = rememberTextFieldState(), textStyle = TextStyle(brush = brush)
)

Yalnızca bir metin parçasını özelleştirmek için linearGradient ile birlikte buildAnnotatedString ve SpanStyle'i kullanma.
Şekil 1. TextField içeriği için gökkuşağı degrade efekti.

Metin alanı durumunu yönetme

TextField, içeriği ve mevcut seçimi için TextFieldState adlı özel bir durum tutucu sınıfı kullanır. TextFieldState, mimarinize uygun olan her yere yerleştirilmek üzere tasarlanmıştır. TextFieldState tarafından sağlanan 2 ana özellik vardır:

  • initialText: TextField öğesinin içeriği.
  • initialSelection: İmlecin veya seçimin şu anda nerede olduğunu gösterir.

TextFieldStateonValueChange geri çağırma gibi diğer yaklaşımlardan ayıran özellik, TextFieldState'ün giriş akışının tamamını tamamen kapsamasıdır. Doğru destekleyici veri yapılarını kullanma, filtreleri ve biçimlendiricileri satır içi olarak yerleştirme ve farklı kaynaklardan gelen tüm düzenlemeleri senkronize etme de bu kapsamdadır.

TextField'te durumu kaldırmak için TextFieldState() öğesini kullanabilirsiniz. Bunun için rememberTextFieldState() işlevini kullanmanızı öneririz. rememberTextFieldState(), bileşeninizde TextFieldState örneğini oluşturur, durum nesnesinin hatırlanmasını sağlar ve yerleşik kayıt ve geri yükleme işlevi sunar:

val usernameState = rememberTextFieldState()
TextField(
    state = usernameState,
    lineLimits = TextFieldLineLimits.SingleLine,
    placeholder = { Text("Enter Username") }
)

rememberTextFieldState, boş bir parametreye sahip olabilir veya metnin ilk değerindeki değerini temsil etmek için iletilen bir başlangıç değerine sahip olabilir. Sonraki bir yeniden oluşturma işleminde farklı bir değer iletilirse durumun değeri güncellenmez. Durumu, başlatıldıktan sonra güncellemek için TextFieldState üzerinde düzenleme yöntemlerini çağırın.

TextField(
    state = rememberTextFieldState(initialText = "Username"),
    lineLimits = TextFieldLineLimits.SingleLine,
)

Metin alanında Kullanıcı adı metninin göründüğü bir TextField.
Şekil 2. TextField ileti dizisi oluşturun.

TextFieldBuffer ile metni değiştirme

TextFieldBuffer, StringBuilder'a benzer işlevlere sahip düzenlenebilir bir metin kapsayıcısı görevi görür. Hem metin içeriğini hem de mevcut seçimle ilgili bilgileri içerir.

TextFieldState.edit, InputTransformation.transformInput veya OutputTransformation.transformOutput gibi işlevlerde genellikle alıcı kapsamı olarak TextFieldBuffer ile karşılaşırsınız. Bu işlevlerde, TextFieldBuffer değerini gerektiği gibi okuyabilir veya güncelleyebilirsiniz. Daha sonra bu değişiklikler TextFieldState için TextFieldState'e bağlanır veya OutputTransformation için oluşturma ardışık düzenine aktarılır.

Tamponun içeriğini değiştirmek için append, insert, replace veya delete gibi standart düzenleme işlevlerini kullanabilirsiniz. Seçim durumunu değiştirmek için doğrudan selection: TextRange değişkenini ayarlayın veya placeCursorAtEnd ya da selectAll gibi yardımcı işlevleri kullanın. Seçim, başlangıç dizininin dahil ve bitiş dizininin hariç olduğu bir TextRange ile temsil edilir. Başlangıç ve bitiş değerleri aynı olan bir TextRange ((3, 3) gibi), şu anda seçili karakter bulunmayan bir imleç konumunu gösterir.

val phoneNumberState = rememberTextFieldState()

LaunchedEffect(phoneNumberState) {
    phoneNumberState.edit { // TextFieldBuffer scope
        append("123456789")
    }
}

TextField(
    state = phoneNumberState,
    inputTransformation = InputTransformation { // TextFieldBuffer scope
        if (asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    },
    outputTransformation = OutputTransformation {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
)

TextFieldState'teki metni düzenleme

Durumu doğrudan durum değişkeniniz aracılığıyla düzenlemenize olanak tanıyan birkaç yöntem vardır:

  • edit: Durum içeriklerini düzenlemenize olanak tanır ve insert, replace, append gibi yöntemleri kullanabilmeniz için TextFieldBuffer işlevleri sağlar.

    val usernameState = rememberTextFieldState("I love Android")
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    usernameState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    usernameState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • setTextAndPlaceCursorAtEnd: Mevcut metni temizler, verilen metinle değiştirir ve imleci sonuna getirir.

    usernameState.setTextAndPlaceCursorAtEnd("I really love Android")
    // textFieldState.text : I really love Android
    // textFieldState.selection : TextRange(21, 21)

  • clearText: Tüm metni temizler.

    usernameState.clearText()
    // textFieldState.text :
    // textFieldState.selection : TextRange(0, 0)

Diğer TextFieldState işlevleri için TextFieldState referansına göz atın.

Kullanıcı girişini değiştirme

Aşağıdaki bölümlerde, kullanıcı girişinin nasıl değiştirileceği açıklanmaktadır. Giriş dönüşümü, kullanıcı yazarken TextField girişini filtrelemenize olanak tanır. Çıkış dönüşümü ise kullanıcı girişini ekranda gösterilmeden önce biçimlendirir.

Giriş dönüşümleriyle kullanıcı girişini filtreleme

Giriş dönüşümü, kullanıcıdan gelen girişi filtrelemenize olanak tanır. Örneğin, TextField işlevi ABD telefon numarası alıyorsa yalnızca 10 haneli sayıları kabul etmek isteyebilirsiniz. InputTransformation sonuçları TextFieldState'a kaydedilir.

Yaygın InputTransformation kullanım alanları için yerleşik filtreler vardır. Uzunluğu sınırlamak için InputTransformation.maxLength() numaralı telefonu arayın:

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine,
    inputTransformation = InputTransformation.maxLength(10)
)

Özel giriş dönüşümleri

InputTransformation tek işlevli bir arayüzdür. Özel InputTransformation'inizi uygularken TextFieldBuffer.transformInput'i geçersiz kılmanız gerekir:

class CustomInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
    }
}

Telefon numarası için, yalnızca TextField alanına rakam girilmesine izin veren özel bir giriş dönüşümü ekleyin:

class DigitOnlyInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
        if (!TextUtils.isDigitsOnly(asCharSequence())) {
            revertAllChanges()
        }
    }
}

Zincir giriş dönüşümleri

Metin girişinize birden fazla filtre eklemek için then uzantı işlevini kullanarak InputTransformation'leri birbirine bağlayın. Filtreler sırayla yürütülür. En iyi uygulama olarak, nihayetinde filtrelenecek verilerde gereksiz dönüşümleri önlemek için önce en seçici filtreleri uygulayın.

TextField(
    state = rememberTextFieldState(),
    inputTransformation = InputTransformation.maxLength(6)
        .then(CustomInputTransformation()),
)

Giriş dönüşümleri eklendikten sonra TextField girişi en fazla 10 basamak kabul eder.

Giriş gösterilmeden önce biçimlendirme

OutputTransformation, kullanıcı girişinin ekranda oluşturulmadan önce biçimlendirilmesine olanak tanır. InputTransformation'ten farklı olarak, OutputTransformation aracılığıyla yapılan biçimlendirme TextFieldState'ye kaydedilmez. Önceki telefon numarası örneğini temel alarak, uygun yerlere parantez ve kısa çizgi eklemeniz gerekir:

Parantez, kısa çizgi ve ilgili dizinlerle doğru şekilde biçimlendirilmiş bir ABD telefon numarası.
Şekil 3. Doğru biçimlendirmeye ve ilgili dizinlere sahip bir ABD telefon numarası.

Bu, değere dayalı TextField'lerde VisualTransformation'leri işlemenin güncellenmiş yoludur. Buradaki temel fark, ofset eşlemelerini hesaplamanız gerekmemesidir.

OutputTransformation tek bir soyut yöntem arayüzüdür. Özel bir OutputTransformation uygulamak için transformOutput yöntemini geçersiz kılmanız gerekir:

class CustomOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
    }
}

Telefon numarasını biçimlendirmek için OutputTransformation değerinize 0. dizinde bir açılış parantezi, 4. dizinde bir kapanış parantezi ve 8. dizinde bir kısa çizgi ekleyin:

class PhoneNumberOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
}

Ardından OutputTransformation dosyanızı TextField'a ekleyin:

TextField(
    state = rememberTextFieldState(),
    outputTransformation = PhoneNumberOutputTransformation()
)

Dönüşümlerin birlikte çalışma şekli

Aşağıdaki şemada, metin girişinden dönüşüme ve ardından çıkışa giden akış gösterilmektedir:

Metin girişinin metin çıkışına dönüşmeden önce nasıl dönüşümlerden geçtiğini gösteren görselleştirme.
Şekil 4. Metin girişinin metin çıkışına dönüşmeden önce nasıl dönüşümlerden geçtiğini gösteren bir diyagram.
  1. Giriş, giriş kaynağından alınır.
  2. Giriş, TextFieldState'e kaydedilen bir InputTransformation aracılığıyla filtrelenir.
  3. Giriş, biçimlendirme için bir OutputTransformation üzerinden iletilir.
  4. Giriş, TextField içinde sunulur.

Klavye seçeneklerini ayarlama

TextField, klavye düzeni gibi klavye yapılandırma seçeneklerini ayarlamanıza veya klavye tarafından destekleniyorsa otomatik düzeltmeyi etkinleştirmenize olanak tanır. Yazılım klavyesi burada sağlanan seçeneklere uygun değilse bazı seçenekler garanti edilmeyebilir. Desteklenen klavye seçeneklerinin listesi aşağıda verilmiştir:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

KeyboardOptions sınıfı artık TextFieldState ile entegre olan TextField bileşenleri için özel olarak kullandığınız yeni bir boole parametresi (showKeyboardOnFocus) içeriyor. Bu seçenek, TextField doğrudan kullanıcı etkileşiminden başka yollarla (ör. programatik olarak) odak aldığında yazılım klavyenin davranışını yönetir.

KeyboardOptions.showKeyboardOnFocus doğru değerine ayarlandığında, TextField dolaylı olarak odak alırsa yazılım klavyesi otomatik olarak görünmez. Bu gibi durumlarda, kullanıcının klavyeyi göstermek için TextField simgesine açıkça dokunması gerekir.

Klavye etkileşim mantığını tanımlama

Android'in yazılım klavyesindeki işlem düğmesi, uygulamanızda etkileşimli yanıtlar sağlar. İşlem düğmesini yapılandırma hakkında daha fazla bilgi için Klavye seçeneklerini ayarlama bölümüne bakın.

Kırmızı daire içine alınmış bir yazılım klavyesi işlem düğmesi (onay işareti simgesi).
Şekil 5. Yazılım klavyesi işlem düğmesi.

Kullanıcı bu işlem düğmesine dokunduğunda ne olacağını tanımlamak için onKeyboardAction parametresini kullanın. Bu parametre, KeyboardActionHandler adlı isteğe bağlı işlevsel bir arayüz kabul eder. KeyboardActionHandler arayüzü tek bir yöntem içerir: onKeyboardAction(performDefaultAction: () -> Unit). Bu onKeyboardAction yöntemi için bir uygulama sağlayarak, kullanıcı klavyenin işlem düğmesine bastığında çalışan özel mantık ekleyebilirsiniz.

Çeşitli standart klavye işlem türleri yerleşik varsayılan davranışlarla birlikte gelir. Örneğin, işlem türü olarak ImeAction.Next veya ImeAction.Previous seçildiğinde varsayılan olarak odak sırasıyla sonraki veya önceki giriş alanına kaydırılır. Benzer şekilde, ImeAction.Done olarak ayarlanan bir işlem düğmesi genellikle yazılım klavyesini kapatır. Bu varsayılan işlevler otomatik olarak yürütülür ve KeyboardActionHandler sağlamanızı gerektirmez.

Bu varsayılan işlemlere ek olarak özel davranış da uygulayabilirsiniz. KeyboardActionHandler'ünüzü sağladığınızda onKeyboardAction yöntemi bir performDefaultAction işlevi alır. Mevcut IME işlemiyle ilişkili standart varsayılan davranışı da tetiklemek için bu performDefaultAction() işlevini özel mantığınızdaki herhangi bir noktada çağırabilirsiniz.

TextField(
    state = textFieldViewModel.usernameState,
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
    onKeyboardAction = { performDefaultAction ->
        textFieldViewModel.validateUsername()
        performDefaultAction()
    }
)

Bu snippet'te, kullanıcı adı alanının yer aldığı bir kayıt ekranında sık karşılaşılan bir kullanım durumu gösterilmektedir. Bu alan için ImeAction.Next, klavye işlem düğmesi olarak seçilir. Bu seçim, sonraki şifre alanına hızlı ve sorunsuz bir şekilde geçiş yapmanızı sağlar.

Bu standart gezinmeye ek olarak, kullanıcı şifresini girmeye devam ederken kullanıcı adı için arka planda bir doğrulama işlemi başlatmanız gerekir. Bu özel doğrulama mantığıyla birlikte ImeAction.Next'e özgü varsayılan odak değiştirme davranışının korunması için performDefaultAction() işlevi çağrılır. performDefaultAction() çağrısı, odağın bir sonraki uygun kullanıcı arayüzü öğesine taşınması için temel odak yönetimi sistemini dolaylı olarak tetikler ve beklenen gezinme akışını korur.

Güvenli bir şifre alanı oluşturma

SecureTextField, şifre alanı yazmak için duruma dayalı metin alanlarının üzerine inşa edilmiş bir bileşendir. Varsayılan olarak karakter girişini gizlediği ve kesme ve kopyalama işlemlerini devre dışı bıraktığı için şifre metin alanları oluşturmak üzere SecureTextField kullanmanızı öneririz.

SecureTextField, kullanıcının karakter girişini nasıl göreceğini kontrol eden bir textObfuscationMode içerir. textObfuscationMode için aşağıdaki seçenekler sunulur:

  • Hidden: Tüm girişleri gizler. Masaüstü platformlarda varsayılan davranış.

  • Visible: Tüm girişleri gösterir.

  • RevealLastTyped: Son karakter hariç tüm girişleri gizler. Mobil cihazlarda varsayılan davranış.

Ek kaynaklar