{"id":40889,"date":"2026-03-02T03:30:28","date_gmt":"2026-03-02T00:30:28","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/"},"modified":"2026-03-02T03:30:28","modified_gmt":"2026-03-02T00:30:28","slug":"jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/","title":{"rendered":"Jetpack Compose&#8217;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim"},"content":{"rendered":"<h2>Jetpack Compose&#8217;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim<\/h2>\n<p>Modern mobil uygulamalar\u0131n vazge\u00e7ilmez bir par\u00e7as\u0131 olan formlar, kullan\u0131c\u0131 etkile\u015fiminin temelini olu\u015fturur. Kullan\u0131c\u0131 bilgilerini toplamak, ayarlar\u0131 de\u011fi\u015ftirmek veya bir i\u015flem ba\u015flatmak i\u00e7in formlara ihtiya\u00e7 duyar\u0131z. Jetpack Compose ile Android UI geli\u015ftirme \u015feklimiz k\u00f6kten de\u011fi\u015fti ve form olu\u015fturma s\u00fcreci de bu yeniliklerden nasibini ald\u0131. Bu makalede, Jetpack Compose kullanarak dinamik, do\u011frulanabilir ve kullan\u0131c\u0131 dostu formlar\u0131 nas\u0131l olu\u015fturaca\u011f\u0131n\u0131z\u0131, <code>TextField<\/code> bile\u015feninden ba\u015flayarak do\u011frulama mekanizmalar\u0131na ve form g\u00f6nderimine kadar t\u00fcm detaylar\u0131yla ele alaca\u011f\u0131z.<\/p>\n<h3>Jetpack Compose&#8217;da Form Geli\u015ftirmenin Temelleri<\/h3>\n<p>Jetpack Compose, deklaratif bir UI yap\u0131s\u0131 sunarak form geli\u015ftirmeyi daha sezgisel ve y\u00f6netilebilir hale getirir. Geleneksel XML tabanl\u0131 yakla\u015f\u0131mlar\u0131n aksine, Compose&#8217;da UI durumu ve verileri do\u011frudan kod i\u00e7inde y\u00f6netilir, bu da daha az boilerplate kod ve daha okunabilir bir yap\u0131 anlam\u0131na gelir.<\/p>\n<h4>Neden Jetpack Compose ile Formlar?<\/h4>\n<p>Compose&#8217;un reaktif yap\u0131s\u0131, kullan\u0131c\u0131 giri\u015flerine an\u0131nda tepki vermeyi ve UI&#8217;\u0131 otomatik olarak g\u00fcncellemeyi kolayla\u015ft\u0131r\u0131r. Bu, \u00f6zellikle form do\u011frulama ve hata mesajlar\u0131n\u0131n dinamik olarak g\u00f6sterilmesi gibi durumlarda b\u00fcy\u00fck avantaj sa\u011flar. Bile\u015fen tabanl\u0131 mimarisi sayesinde, form elemanlar\u0131n\u0131 yeniden kullan\u0131labilir par\u00e7ac\u0131klar halinde tasarlayabiliriz.<\/p>\n<h4>Temel Bile\u015fenler: TextField ve Button<\/h4>\n<p>Bir formun en temel yap\u0131 ta\u015flar\u0131, kullan\u0131c\u0131dan veri alan <code>TextField<\/code> ve formu i\u015fleme koyan <code>Button<\/code> bile\u015fenleridir. Compose&#8217;da bu bile\u015fenler, \u00f6zelle\u015ftirilebilir parametrelerle gelir ve form ihtiya\u00e7lar\u0131n\u0131za g\u00f6re kolayca \u015fekillendirilebilir. <code>TextField<\/code>, metin giri\u015fi i\u00e7in, <code>Button<\/code> ise kullan\u0131c\u0131 eylemlerini tetiklemek i\u00e7in kullan\u0131l\u0131r.<\/p>\n<h4>Basit Bir Form Yap\u0131s\u0131 Olu\u015fturma<\/h4>\n<p>Jetpack Compose&#8217;da basit bir form, genellikle bir <code>Column<\/code> i\u00e7inde birden fazla <code>TextField<\/code> ve bir <code>Button<\/code> bar\u0131nd\u0131r\u0131r. Her <code>TextField<\/code> kendi durumunu (kullan\u0131c\u0131n\u0131n girdi\u011fi metin) y\u00f6netir ve bu durumlar <code>remember<\/code> ve <code>mutableStateOf<\/code> ile Compose&#8217;un reaktif sistemine dahil edilir.<\/p>\n<pre><code class=\"language-kotlin\">@Composable\nfun SimpleForm() {\n    var name by remember { mutableStateOf(\"\") }\n    var email by remember { mutableStateOf(\"\") }\n\n    Column(\n        modifier = Modifier\n            .fillMaxSize()\n            .padding(16.dp),\n        horizontalAlignment = Alignment.CenterHorizontally,\n        verticalArrangement = Arrangement.spacedBy(8.dp)\n    ) {\n        OutlinedTextField(\n            value = name,\n            onValueChange = { name = it },\n            label = { Text(\"Ad\u0131n\u0131z\") },\n            modifier = Modifier.fillMaxWidth()\n        )\n        OutlinedTextField(\n            value = email,\n            onValueChange = { email = it },\n            label = { Text(\"E-posta Adresiniz\") },\n            modifier = Modifier.fillMaxWidth()\n        )\n        Button(\n            onClick = { \/* Formu g\u00f6nder *\/ },\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            Text(\"Kaydol\")\n        }\n    }\n}<\/pre>\n<p><\/code><br \/>\nBu \u00f6rnekte, <code>name<\/code> ve <code>email<\/code> de\u011fi\u015fkenleri, <code>TextField<\/code>'lar\u0131n de\u011ferlerini tutar ve <code>onValueChange<\/code> ile g\u00fcncellenir.<\/p>\n<h3>TextField Bile\u015fenini Etkin Kullanma<\/h3>\n<p><code>TextField<\/code> bile\u015feni, kullan\u0131c\u0131dan metin giri\u015fi almak i\u00e7in kullan\u0131lan temel bir UI eleman\u0131d\u0131r. Ancak sadece metin almakla kalmaz, ayn\u0131 zamanda bir\u00e7ok \u00f6zelle\u015ftirme ve davran\u0131\u015f se\u00e7ene\u011fi sunar.<\/p>\n<h4>TextField Parametreleri ve \u00d6zelle\u015ftirme<\/h4>\n<p><code>TextField<\/code> ve <code>OutlinedTextField<\/code> gibi varyantlar, <code>label<\/code>, <code>placeholder<\/code>, <code>leadingIcon<\/code>, <code>trailingIcon<\/code>, <code>keyboardOptions<\/code>, <code>visualTransformation<\/code> gibi bir\u00e7ok parametreye sahiptir. Bu parametreler sayesinde giri\u015f alan\u0131n\u0131n g\u00f6r\u00fcn\u00fcm\u00fcn\u00fc ve davran\u0131\u015f\u0131n\u0131 tamamen kontrol edebilirsiniz. \u00d6rne\u011fin, bir \u015fifre alan\u0131 i\u00e7in <code>visualTransformation<\/code> kullanarak girilen karakterleri gizleyebilirsiniz.<\/p>\n<pre><code class=\"language-kotlin\">@Composable\nfun CustomizedTextField() {\n    var password by remember { mutableStateOf(\"\") }\n    var passwordVisible by remember { mutableStateOf(false) }\n\n    OutlinedTextField(\n        value = password,\n        onValueChange = { password = it },\n        label = { Text(\"\u015eifre\") },\n        visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),\n        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),\n        trailingIcon = {\n            val image = if (passwordVisible)\n                Icons.Filled.Visibility\n            else Icons.Filled.VisibilityOff\n            val description = if (passwordVisible) \"\u015eifreyi gizle\" else \"\u015eifreyi g\u00f6ster\"\n\n            IconButton(onClick = { passwordVisible = !passwordVisible }) {\n                Icon(imageVector = image, description)\n            }\n        },\n        modifier = Modifier.fillMaxWidth()\n    )\n}<\/pre>\n<p><\/code><br \/>\nBu \u00f6rnek, \u015fifre alan\u0131nda metni gizleme ve bir g\u00f6r\u00fcn\u00fcrl\u00fck ikonu ekleme gibi geli\u015fmi\u015f \u00f6zelle\u015ftirmeleri g\u00f6stermektedir.<\/p>\n<h4>Klavye T\u00fcrleri ve G\u00f6rsel \u0130pu\u00e7lar\u0131<\/h4>\n<p><code>KeyboardOptions<\/code> ile klavyenin t\u00fcr\u00fcn\u00fc (say\u0131sal, e-posta, metin vb.) ve <code>imeAction<\/code> ile klavyedeki \"Enter\" tu\u015funun ne yapaca\u011f\u0131n\u0131 belirleyebilirsiniz. Bu, kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir. <code>label<\/code> ve <code>placeholder<\/code> gibi g\u00f6rsel ipu\u00e7lar\u0131 da kullan\u0131c\u0131ya hangi t\u00fcr verinin beklendi\u011fi konusunda rehberlik eder.<\/p>\n<h4>Durum Y\u00f6netimi: <code>remember<\/code> ve <code>mutableStateOf<\/code><\/h4>\n<p>Compose'da <code>TextField<\/code>'\u0131n de\u011feri, harici bir durum de\u011fi\u015fkeni taraf\u0131ndan y\u00f6netilir. Bu durum de\u011fi\u015fkeni, <code>remember { mutableStateOf(\"\") }<\/code> kullan\u0131larak olu\u015fturulur. <code>remember<\/code> fonksiyonu, Composable'\u0131n yeniden olu\u015fturulmas\u0131 durumunda bile durumun korunmas\u0131n\u0131 sa\u011flarken, <code>mutableStateOf<\/code> ise durumun de\u011fi\u015febilir oldu\u011funu ve de\u011fi\u015fimlerde UI'\u0131n yeniden \u00e7izilmesini tetikleyece\u011fini belirtir.<\/p>\n<h3>Kullan\u0131c\u0131 Giri\u015flerini Do\u011frulama ve Hata Y\u00f6netimi<\/h3>\n<p>Form do\u011frulama, uygulaman\u0131z\u0131n tutarl\u0131 ve do\u011fru veriler almas\u0131n\u0131 sa\u011flamak i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131ya an\u0131nda geri bildirim vermek, hata oran\u0131n\u0131 d\u00fc\u015f\u00fcr\u00fcr ve kullan\u0131c\u0131 deneyimini iyile\u015ftirir.<\/p>\n<h4>Temel Do\u011frulama Kurallar\u0131 (Bo\u015fluk Kontrol\u00fc, Minimum Uzunluk)<\/h4>\n<p>En basit do\u011frulama, bir alan\u0131n bo\u015f b\u0131rak\u0131l\u0131p b\u0131rak\u0131lmad\u0131\u011f\u0131n\u0131 veya belirli bir minimum uzunlu\u011fa sahip olup olmad\u0131\u011f\u0131n\u0131 kontrol etmektir. Bu t\u00fcr kontroller genellikle <code>if<\/code> ifadeleriyle yap\u0131l\u0131r ve do\u011frulama hatas\u0131 durumunda bir boolean de\u011fi\u015fkeni g\u00fcncellenir.<\/p>\n<pre><code class=\"language-kotlin\">@Composable\nfun ValidationExample() {\n    var username by remember { mutableStateOf(\"\") }\n    var usernameError by remember { mutableStateOf(false) }\n\n    Column(modifier = Modifier.padding(16.dp)) {\n        OutlinedTextField(\n            value = username,\n            onValueChange = {\n                username = it\n                usernameError = it.isBlank() || it.length < 3\n            },\n            label = { Text(\"Kullan\u0131c\u0131 Ad\u0131\") },\n            isError = usernameError,\n            modifier = Modifier.fillMaxWidth()\n        )\n        if (usernameError) {\n            Text(\n                text = \"Kullan\u0131c\u0131 ad\u0131 bo\u015f olamaz ve en az 3 karakter olmal\u0131.\",\n                color = MaterialTheme.colors.error,\n                style = MaterialTheme.typography.caption,\n                modifier = Modifier.padding(start = 16.dp)\n            )\n        }\n        \/\/ ... Di\u011fer alanlar ve buton\n    }\n}<\/pre>\n<p><\/code><br \/>\n<code>isError<\/code> parametresi <code>TextField<\/code>'\u0131n g\u00f6rsel olarak hata durumunda oldu\u011funu belirtir ve genellikle k\u0131rm\u0131z\u0131 bir vurgu ile g\u00f6sterilir.<\/p>\n<h4>Geli\u015fmi\u015f Do\u011frulama (E-posta, Regex)<\/h4>\n<p>Daha karma\u015f\u0131k do\u011frulamalar i\u00e7in d\u00fczenli ifadeler (Regex) kullanmak yayg\u0131n bir y\u00f6ntemdir. \u00d6rne\u011fin, bir e-posta adresinin ge\u00e7erli bir formatta olup olmad\u0131\u011f\u0131n\u0131 kontrol etmek i\u00e7in Regex kullan\u0131labilir.<\/p>\n<pre><code class=\"language-kotlin\">fun isValidEmail(email: String): Boolean {\n    return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()\n}\n\/\/ ...\n\/\/ onValueChange i\u00e7inde: emailError = !isValidEmail(it)<\/pre>\n<p><\/code><\/p>\n<h4>Hata Mesajlar\u0131n\u0131 G\u00f6sterme<\/h4>\n<p>Hata mesajlar\u0131, kullan\u0131c\u0131ya neyin yanl\u0131\u015f gitti\u011fini a\u00e7\u0131k\u00e7a belirtmelidir. <code>TextField<\/code>'\u0131n hemen alt\u0131nda <code>Text<\/code> bile\u015feni kullanarak hata mesajlar\u0131n\u0131 g\u00f6sterebilirsiniz. <code>isError<\/code> parametresiyle birlikte kullan\u0131ld\u0131\u011f\u0131nda, bu mesajlar sadece hata durumunda g\u00f6r\u00fcn\u00fcr hale gelir.<\/p>\n<h3>Jetpack Compose'da Form Durum Y\u00f6netimi<\/h3>\n<p>Form durumunu etkili bir \u015fekilde y\u00f6netmek, \u00f6zellikle karma\u015f\u0131k formlarda uygulaman\u0131n \u00f6l\u00e7eklenebilirli\u011fi ve s\u00fcrd\u00fcr\u00fclebilirli\u011fi i\u00e7in hayati \u00f6neme sahiptir.<\/p>\n<h4>Basit Durum Y\u00f6netimi Yakla\u015f\u0131mlar\u0131<\/h4>\n<p>Yukar\u0131daki \u00f6rneklerde g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi, her <code>TextField<\/code> i\u00e7in ayr\u0131 <code>mutableStateOf<\/code> de\u011fi\u015fkenleri tan\u0131mlamak, basit formlar i\u00e7in yeterli olabilir. Ancak form b\u00fcy\u00fcd\u00fck\u00e7e bu yakla\u015f\u0131m kod tekrar\u0131na ve y\u00f6netilmesi zor bir yap\u0131ya yol a\u00e7abilir.<\/p>\n<h4>ViewModel ile Durum Y\u00f6netimi<\/h4>\n<p>Daha b\u00fcy\u00fck ve karma\u015f\u0131k formlar i\u00e7in <code>ViewModel<\/code> kullanmak en iyi uygulamalardan biridir. <code>ViewModel<\/code>, yap\u0131land\u0131rma de\u011fi\u015fikliklerinde (\u00f6rne\u011fin ekran d\u00f6nd\u00fcrme) verilerin kaybolmamas\u0131n\u0131 sa\u011flar ve UI'dan i\u015f mant\u0131\u011f\u0131n\u0131 ay\u0131r\u0131r. Bir <code>ViewModel<\/code> i\u00e7inde t\u00fcm form alanlar\u0131n\u0131n durumunu ve do\u011frulama mant\u0131\u011f\u0131n\u0131 tutabilirsiniz.<\/p>\n<pre><code class=\"language-kotlin\">class LoginFormViewModel : ViewModel() {\n    var username by mutableStateOf(\"\")\n        private set\n    var password by mutableStateOf(\"\")\n        private set\n\n    var usernameError by mutableStateOf(false)\n        private set\n    var passwordError by mutableStateOf(false)\n        private set\n\n    fun updateUsername(newUsername: String) {\n        username = newUsername\n        usernameError = newUsername.isBlank() || newUsername.length < 3\n    }\n\n    fun updatePassword(newPassword: String) {\n        password = newPassword\n        passwordError = newPassword.isBlank() || newPassword.length < 6\n    }\n\n    fun validateForm(): Boolean {\n        usernameError = username.isBlank() || username.length < 3\n        passwordError = password.isBlank() || password.length < 6\n        return !usernameError &#038;&#038; !passwordError\n    }\n\n    fun submitForm() {\n        if (validateForm()) {\n            \/\/ Formu g\u00f6nder\n            println(\"Form g\u00f6nderildi: Kullan\u0131c\u0131 Ad\u0131: $username, \u015eifre: $password\")\n        }\n    }\n}\n\n@Composable\nfun LoginForm(viewModel: LoginFormViewModel = viewModel()) {\n    Column(modifier = Modifier.padding(16.dp)) {\n        OutlinedTextField(\n            value = viewModel.username,\n            onValueChange = { viewModel.updateUsername(it) },\n            label = { Text(\"Kullan\u0131c\u0131 Ad\u0131\") },\n            isError = viewModel.usernameError,\n            modifier = Modifier.fillMaxWidth()\n        )\n        if (viewModel.usernameError) {\n            Text(\"Kullan\u0131c\u0131 ad\u0131 bo\u015f olamaz ve en az 3 karakter olmal\u0131.\", color = MaterialTheme.colors.error)\n        }\n        \/\/ ... \u015eifre alan\u0131 ve hata mesaj\u0131\n        Button(\n            onClick = { viewModel.submitForm() },\n            enabled = !viewModel.usernameError &#038;&#038; !viewModel.passwordError &#038;&#038; viewModel.username.isNotBlank() &#038;&#038; viewModel.password.isNotBlank(),\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            Text(\"Giri\u015f Yap\")\n        }\n    }\n}<\/pre>\n<p><\/code><br \/>\nBu yakla\u015f\u0131m, formun t\u00fcm durumunu tek bir yerde toplar ve Composable'\u0131n daha temiz kalmas\u0131n\u0131 sa\u011flar.<\/p>\n<h4>\u00d6zel Form Durumu S\u0131n\u0131flar\u0131 Olu\u015fturma<\/h4>\n<p>Daha da karma\u015f\u0131k senaryolarda, her bir form alan\u0131 i\u00e7in \u00f6zel bir durum s\u0131n\u0131f\u0131 (\u00f6rne\u011fin <code>FormFieldState<\/code>) olu\u015fturarak do\u011frulama mant\u0131\u011f\u0131n\u0131 ve hata mesajlar\u0131n\u0131 ilgili alanla birle\u015ftirebilirsiniz. Bu, \u00f6zellikle \u00e7ok say\u0131da alan ve karma\u015f\u0131k do\u011frulama kurallar\u0131 olan formlarda kodun daha mod\u00fcler olmas\u0131n\u0131 sa\u011flar.<\/p>\n<h3>Form G\u00f6nderimi ve Veri \u0130\u015fleme<\/h3>\n<p>Formun son ad\u0131m\u0131, kullan\u0131c\u0131 taraf\u0131ndan girilen verileri toplamak, do\u011frulamak ve bir sunucuya g\u00f6ndermek veya yerel olarak i\u015flemek \u00fczere tetiklemektir.<\/p>\n<h4>G\u00f6nder Butonu ve Etkinle\u015ftirme Ko\u015fullar\u0131<\/h4>\n<p>G\u00f6nder butonu, genellikle t\u00fcm form alanlar\u0131 ge\u00e7erli olana kadar devre d\u0131\u015f\u0131 b\u0131rak\u0131l\u0131r. Bu, <code>Button<\/code> bile\u015feninin <code>enabled<\/code> parametresiyle kontrol edilir. T\u00fcm alanlar\u0131n ge\u00e7erli olup olmad\u0131\u011f\u0131n\u0131 kontrol eden bir boolean de\u011fi\u015fkeni veya <code>ViewModel<\/code>'daki bir fonksiyon bu ko\u015fulu sa\u011flayabilir.<\/p>\n<h4>Verilerin Toplanmas\u0131 ve \u0130\u015flenmesi<\/h4>\n<p>Kullan\u0131c\u0131 \"G\u00f6nder\" butonuna t\u0131klad\u0131\u011f\u0131nda, <code>ViewModel<\/code> i\u00e7indeki ilgili fonksiyon tetiklenir. Bu fonksiyon, form alanlar\u0131ndaki mevcut de\u011ferleri toplar ve gerekli i\u015f mant\u0131\u011f\u0131n\u0131 (\u00f6rne\u011fin bir API \u00e7a\u011fr\u0131s\u0131) y\u00fcr\u00fct\u00fcr.<\/p>\n<h4>Asenkron \u0130\u015flemler ve Y\u00fckleme Durumu<\/h4>\n<p>Form g\u00f6nderimi genellikle bir a\u011f iste\u011fi gibi asenkron bir i\u015flem i\u00e7erir. Bu t\u00fcr durumlarda, kullan\u0131c\u0131ya i\u015flemin devam etti\u011fini bildirmek i\u00e7in bir y\u00fckleme g\u00f6stergesi (\u00f6rne\u011fin <code>CircularProgressIndicator<\/code>) g\u00f6stermek \u00f6nemlidir. <code>ViewModel<\/code> i\u00e7inde bir <code>isLoading<\/code> durumu tutarak bu g\u00f6stergeyi kontrol edebilirsiniz.<\/p>\n<pre><code class=\"language-kotlin\">class SubmissionViewModel : ViewModel() {\n    \/\/ ... form alanlar\u0131 ve do\u011frulama\n    var isLoading by mutableStateOf(false)\n        private set\n    var submissionSuccess by mutableStateOf<Boolean?>(null)\n        private set\n\n    fun submitForm() {\n        if (validateForm()) {\n            isLoading = true\n            \/\/ Simulate network request\n            viewModelScope.launch {\n                delay(2000) \/\/ 2 saniye bekle\n                \/\/ API \u00e7a\u011fr\u0131s\u0131 sonucuna g\u00f6re submissionSuccess'i ayarla\n                submissionSuccess = true \/\/ veya false\n                isLoading = false\n            }\n        }\n    }\n}\n\n@Composable\nfun SubmissionForm(viewModel: SubmissionViewModel = viewModel()) {\n    \/\/ ... TextField'lar\n    Button(\n        onClick = { viewModel.submitForm() },\n        enabled = !viewModel.isLoading && viewModel.validateForm(), \/\/ isLoading durumunu da ekledik\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        if (viewModel.isLoading) {\n            CircularProgressIndicator(color = Color.White, modifier = Modifier.size(24.dp))\n        } else {\n            Text(\"G\u00f6nder\")\n        }\n    }\n    viewModel.submissionSuccess?.let { success ->\n        if (success) {\n            Text(\"Form ba\u015far\u0131yla g\u00f6nderildi!\", color = Color.Green)\n        } else {\n            Text(\"Form g\u00f6nderilirken bir hata olu\u015ftu.\", color = Color.Red)\n        }\n    }\n}<\/pre>\n<p><\/code><br \/>\nBu yap\u0131, kullan\u0131c\u0131ya ak\u0131c\u0131 ve bilgilendirici bir deneyim sunar.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Jetpack Compose, Android'de form olu\u015fturma s\u00fcrecini basitle\u015ftiren ve modernle\u015ftiren g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r. <code>TextField<\/code> bile\u015feninin esnekli\u011fi, reaktif durum y\u00f6netimi yetenekleri ve <code>ViewModel<\/code> ile i\u015f mant\u0131\u011f\u0131n\u0131 ay\u0131rma imkan\u0131 sayesinde, karma\u015f\u0131k formlar\u0131 bile temiz, s\u00fcrd\u00fcr\u00fclebilir ve test edilebilir bir \u015fekilde geli\u015ftirebilirsiniz. Do\u011frulama ve hata y\u00f6netimi, kullan\u0131c\u0131 deneyiminin temel ta\u015flar\u0131d\u0131r ve Compose bu s\u00fcre\u00e7leri dinamik olarak ele almak i\u00e7in m\u00fckemmel bir \u00e7er\u00e7eve sunar. Bu makaledeki teknikleri uygulayarak, uygulaman\u0131z i\u00e7in sa\u011flam ve kullan\u0131c\u0131 dostu formlar olu\u015fturmaya ba\u015flayabilirsiniz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<h4>Jetpack Compose'da form do\u011frulama neden \u00f6nemlidir?<\/h4>\n<p>Form do\u011frulama, uygulaman\u0131z\u0131n do\u011fru ve ge\u00e7erli veriler almas\u0131n\u0131 sa\u011flar, veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc korur ve hatal\u0131 giri\u015flerden kaynaklanan sorunlar\u0131 \u00f6nler. Ayr\u0131ca, kullan\u0131c\u0131ya an\u0131nda geri bildirim sa\u011flayarak daha iyi bir kullan\u0131c\u0131 deneyimi sunar.<\/p>\n<h4>Form durumunu y\u00f6netmek i\u00e7in en iyi y\u00f6ntem nedir?<\/h4>\n<p>Basit formlar i\u00e7in <code>remember<\/code> ve <code>mutableStateOf<\/code> yeterli olsa da, karma\u015f\u0131k formlarda <code>ViewModel<\/code> kullanmak en iyi uygulamad\u0131r. <code>ViewModel<\/code>, UI'dan i\u015f mant\u0131\u011f\u0131n\u0131 ay\u0131r\u0131r, yap\u0131land\u0131rma de\u011fi\u015fikliklerinde veri kayb\u0131n\u0131 \u00f6nler ve test edilebilirli\u011fi art\u0131r\u0131r.<\/p>\n<h4>\u00c7ok ad\u0131ml\u0131 formlar Jetpack Compose'da nas\u0131l olu\u015fturulur?<\/h4>\n<p>\u00c7ok ad\u0131ml\u0131 formlar, genellikle her ad\u0131m i\u00e7in ayr\u0131 bir Composable fonksiyonu veya <code>ViewModel<\/code> i\u00e7inde bir <code>currentStep<\/code> durumu tutularak olu\u015fturulur. <code>AnimatedContent<\/code> veya <code>Crossfade<\/code> gibi bile\u015fenler, ad\u0131mlar aras\u0131nda ak\u0131c\u0131 ge\u00e7i\u015fler sa\u011flamak i\u00e7in kullan\u0131labilir.<\/p>\n<h4>TextField'da klavye t\u00fcr\u00fcn\u00fc nas\u0131l de\u011fi\u015ftiririm?<\/h4>\n<p><code>TextField<\/code> bile\u015feninin <code>keyboardOptions<\/code> parametresini kullanarak klavye t\u00fcr\u00fcn\u00fc de\u011fi\u015ftirebilirsiniz. \u00d6rne\u011fin, say\u0131sal giri\u015f i\u00e7in <code>KeyboardOptions(keyboardType = KeyboardType.Number)<\/code> kullanabilirsiniz.<\/p>\n<h4>Hata mesajlar\u0131n\u0131 kullan\u0131c\u0131ya nas\u0131l g\u00f6steririm?<\/h4>\n<p>Hata mesajlar\u0131n\u0131, <code>TextField<\/code>'\u0131n <code>isError<\/code> parametresiyle birlikte, genellikle <code>TextField<\/code>'\u0131n hemen alt\u0131nda bir <code>Text<\/code> bile\u015feni kullanarak g\u00f6sterebilirsiniz. <code>isError<\/code> true oldu\u011funda, <code>Text<\/code> bile\u015feni g\u00f6r\u00fcn\u00fcr hale gelir ve hata mesaj\u0131n\u0131 g\u00f6sterir.<\/p>\n","protected":false},"excerpt":{"rendered":"Jetpack Compose&#8217;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim Modern mobil uygulamalar\u0131n vazge\u00e7ilmez bir par\u00e7as\u0131 olan formlar, kullan\u0131c\u0131 etkile\u015fiminin temelini olu\u015fturur.","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-40889","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Jetpack Compose&#039;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Jetpack Compose&#039;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim\" \/>\n<meta property=\"og:description\" content=\"Jetpack Compose&#039;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim Modern mobil uygulamalar\u0131n vazge\u00e7ilmez bir par\u00e7as\u0131 olan formlar, kullan\u0131c\u0131 etkile\u015fiminin temelini olu\u015fturur.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-03-02T00:30:28+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Jetpack Compose&#8217;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim\",\"datePublished\":\"2026-03-02T00:30:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/\"},\"wordCount\":1582,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/\",\"name\":\"Jetpack Compose'da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-03-02T00:30:28+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Jetpack Compose&#8217;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Jetpack Compose'da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/","og_locale":"tr_TR","og_type":"article","og_title":"Jetpack Compose'da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim","og_description":"Jetpack Compose'da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim Modern mobil uygulamalar\u0131n vazge\u00e7ilmez bir par\u00e7as\u0131 olan formlar, kullan\u0131c\u0131 etkile\u015fiminin temelini olu\u015fturur.","og_url":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-03-02T00:30:28+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"11 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Jetpack Compose&#8217;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim","datePublished":"2026-03-02T00:30:28+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/"},"wordCount":1582,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/","url":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/","name":"Jetpack Compose'da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-03-02T00:30:28+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-composeda-form-olusturma-textfield-dogrulama-ve-gonderim\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Jetpack Compose&#8217;da Form Olu\u015fturma: TextField, Do\u011frulama ve G\u00f6nderim"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/40889","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=40889"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/40889\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=40889"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=40889"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=40889"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}