Skip to content

Commit 45244fc

Browse files
committed
State based TF snippets
1 parent 70285ac commit 45244fc

File tree

1 file changed

+304
-0
lines changed

1 file changed

+304
-0
lines changed
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
package com.example.compose.snippets.text
2+
3+
import android.text.TextUtils
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.foundation.text.BasicTextField
7+
import androidx.compose.foundation.text.KeyboardOptions
8+
import androidx.compose.foundation.text.input.InputTransformation
9+
import androidx.compose.foundation.text.input.OutputTransformation
10+
import androidx.compose.foundation.text.input.TextFieldBuffer
11+
import androidx.compose.foundation.text.input.TextFieldLineLimits
12+
import androidx.compose.foundation.text.input.TextFieldState
13+
import androidx.compose.foundation.text.input.clearText
14+
import androidx.compose.foundation.text.input.insert
15+
import androidx.compose.foundation.text.input.maxLength
16+
import androidx.compose.foundation.text.input.rememberTextFieldState
17+
import androidx.compose.foundation.text.input.selectAll
18+
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
19+
import androidx.compose.foundation.text.input.then
20+
import androidx.compose.material.SecureTextField
21+
import androidx.compose.material.TextField
22+
23+
import androidx.compose.material3.Button
24+
import androidx.compose.material3.CircularProgressIndicator
25+
import androidx.compose.material3.Text
26+
import androidx.compose.runtime.Composable
27+
import androidx.compose.runtime.getValue
28+
import androidx.compose.runtime.mutableStateOf
29+
import androidx.compose.runtime.remember
30+
import androidx.compose.runtime.setValue
31+
import androidx.compose.ui.Modifier
32+
import androidx.compose.ui.graphics.Brush
33+
import androidx.compose.ui.graphics.Color
34+
import androidx.compose.ui.text.TextStyle
35+
import androidx.compose.ui.text.font.FontWeight
36+
import androidx.compose.ui.text.input.ImeAction
37+
import androidx.compose.ui.tooling.preview.Preview
38+
import androidx.compose.ui.unit.dp
39+
import androidx.lifecycle.ViewModel
40+
import androidx.lifecycle.viewModelScope
41+
import kotlinx.coroutines.launch
42+
43+
@Composable
44+
fun StateBasedTextSnippets() {
45+
// [START android_compose_state_text_1]
46+
BasicTextField(state = rememberTextFieldState())
47+
48+
TextField(state = rememberTextFieldState())
49+
// [END android_compose_state_text_1]
50+
}
51+
52+
@Composable
53+
fun StyleTextField() {
54+
// [START android_compose_state_text_2]
55+
TextField(
56+
state = rememberTextFieldState(),
57+
lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2),
58+
placeholder = { Text("") },
59+
textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
60+
modifier = Modifier.padding(20.dp)
61+
)
62+
// [END android_compose_state_text_2]
63+
}
64+
65+
@Composable
66+
fun ConfigureLineLimits() {
67+
// [START android_compose_state_text_3]
68+
TextField(
69+
state = rememberTextFieldState(),
70+
lineLimits = TextFieldLineLimits.SingleLine
71+
)
72+
// [END android_compose_state_text_3]
73+
74+
// [START android_compose_state_text_4]
75+
TextField(
76+
state = rememberTextFieldState(),
77+
lineLimits = TextFieldLineLimits.MultiLine(1, 4)
78+
)
79+
// [END android_compose_state_text_4]
80+
}
81+
82+
@Composable
83+
fun StyleWithBrush() {
84+
// [START android_compose_state_text_5]
85+
val brush = remember {
86+
Brush.linearGradient(
87+
colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta)
88+
)
89+
}
90+
TextField(
91+
state = rememberTextFieldState(), textStyle = TextStyle(brush = brush)
92+
)
93+
// [END android_compose_state_text_5]
94+
}
95+
96+
// [START android_compose_state_text_6]
97+
// TODO fix this snippet
98+
//val usernameState = rememberTextFieldState()
99+
//TextField(
100+
//state = usernameState,
101+
//lineLimits = TextFieldLineLimits.SingleLine,
102+
//placeholder = { Text("Enter Username") }
103+
//)
104+
val LoginRepository = "repository"
105+
106+
class LoginViewModel(val loginRepository: Repository): ViewModel() {
107+
val username = TextFieldState()
108+
val password = TextFieldState()
109+
110+
val isLoginButtonEnabled: Boolean
111+
get() = !isLoginButtonLoading && username.text.length > 6 && password.text.length > 6
112+
113+
var isLoginButtonLoading by mutableStateOf(false)
114+
private set
115+
116+
fun loginButtonClick() {
117+
viewModelScope.launch {
118+
isLoginButtonLoading = true
119+
val result = loginRepository.login(
120+
username.text.toString(),
121+
password.text.toString()
122+
)
123+
// process result
124+
isLoginButtonLoading = false
125+
}
126+
}
127+
}
128+
129+
@Composable
130+
fun LoginForm(
131+
viewModel: LoginViewModel,
132+
modifier: Modifier
133+
) {
134+
Column(modifier) {
135+
TextField(viewModel.username)
136+
SecureTextField(viewModel.password)
137+
Button(
138+
onClick = viewModel::loginButtonClick,
139+
enabled = viewModel.isLoginButtonEnabled
140+
) {
141+
if (viewModel.isLoginButtonLoading) {
142+
CircularProgressIndicator()
143+
} else {
144+
Text("Login")
145+
}
146+
}
147+
}
148+
}
149+
// [END android_compose_state_text_6]
150+
151+
class Repository {
152+
fun login(username: String, password: String) {
153+
154+
}
155+
}
156+
157+
@Composable
158+
fun TextFieldPlaceholder() {
159+
160+
}
161+
162+
@Preview
163+
@Composable
164+
fun TextFieldInitialState() {
165+
// [START android_compose_state_text_7]
166+
TextField(
167+
state = rememberTextFieldState(initialText = "Username"),
168+
lineLimits = TextFieldLineLimits.SingleLine,
169+
)
170+
// [END android_compose_state_text_7]
171+
}
172+
173+
@Composable
174+
fun TextFieldBuffer() {
175+
// [START android_compose_state_text_8]
176+
// [END android_compose_state_text_8]
177+
// [START android_compose_state_text_9]
178+
// [END android_compose_state_text_9]
179+
}
180+
181+
@Preview
182+
@Composable
183+
fun EditTextFieldState() {
184+
// [START android_compose_state_text_10]
185+
val usernameState = rememberTextFieldState("I love Android")
186+
// textFieldState.text : I love Android
187+
// textFieldState.selection: TextRange(14, 14)
188+
usernameState.edit { insert(14, "!") }
189+
// textFieldState.text : I love Android!
190+
// textFieldState.selection: TextRange(15, 15)
191+
usernameState.edit { replace(7, 14, "Compose") }
192+
// textFieldState.text : I love Compose!
193+
// textFieldState.selection: TextRange(15, 15)
194+
usernameState.edit { append("!!!") }
195+
// textFieldState.text : I love Compose!!!!
196+
// textFieldState.selection: TextRange(18, 18)
197+
usernameState.edit { selectAll() }
198+
// textFieldState.text : I love Compose!!!!
199+
// textFieldState.selection: TextRange(0, 18)
200+
// [END android_compose_state_text_10]
201+
202+
// [END android_compose_state_text_11]
203+
usernameState.setTextAndPlaceCursorAtEnd("I really love Android")
204+
// textFieldState.text : I really love Android
205+
// textFieldState.selection : TextRange(21, 21)
206+
// [END android_compose_state_text_11]
207+
208+
// [END android_compose_state_text_12]
209+
usernameState.clearText()
210+
// textFieldState.text :
211+
// textFieldState.selection : TextRange(0, 0)
212+
// [END android_compose_state_text_12]
213+
}
214+
215+
class TextFieldViewModel : ViewModel() {
216+
fun validateUsername() {
217+
218+
}
219+
}
220+
val textFieldViewModel = TextFieldViewModel()
221+
@Composable
222+
fun TextFieldKeyboardOptions() {
223+
// [START android_compose_state_text_13]
224+
BasicTextField(
225+
state = rememberTextFieldState(),
226+
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
227+
onKeyboardAction = { performDefaultAction ->
228+
textFieldViewModel.validateUsername()
229+
performDefaultAction()
230+
}
231+
)
232+
// [END android_compose_state_text_13]
233+
}
234+
235+
236+
237+
@Composable
238+
fun TextFieldInputTransformation() {
239+
// [START android_compose_state_text_14]
240+
TextField(
241+
state = rememberTextFieldState(),
242+
lineLimits = TextFieldLineLimits.SingleLine,
243+
inputTransformation = InputTransformation.maxLength(10)
244+
)
245+
// [END android_compose_state_text_14]
246+
247+
// [START android_compose_state_text_17]
248+
TextField(
249+
state = rememberTextFieldState(),
250+
inputTransformation = InputTransformation.maxLength(6)
251+
.then(CustomInputTransformation()),
252+
)
253+
// [END android_compose_state_text_17]
254+
255+
}
256+
257+
// [START android_compose_state_text_15]
258+
class CustomInputTransformation : InputTransformation {
259+
override fun TextFieldBuffer.transformInput() {
260+
261+
262+
}
263+
}
264+
// [END android_compose_state_text_15]
265+
266+
// [START android_compose_state_text_16]
267+
class DigitOnlyInputTransformation : InputTransformation {
268+
override fun TextFieldBuffer.transformInput() {
269+
if (!TextUtils.isDigitsOnly(asCharSequence())) {
270+
revertAllChanges()
271+
}
272+
}
273+
}
274+
// [END android_compose_state_text_16]
275+
276+
// [START android_compose_state_text_17]
277+
class CustomOutputTransformation : OutputTransformation {
278+
override fun TextFieldBuffer.transformOutput() {
279+
280+
281+
}
282+
}
283+
// [END android_compose_state_text_17]
284+
285+
// [START android_compose_state_text_18]
286+
class PhoneNumberOutputTransformation : OutputTransformation {
287+
override fun TextFieldBuffer.transformOutput() {
288+
if (length > 0) insert(0, "(")
289+
if (length > 4) insert(4, ")")
290+
if (length > 8) insert(8, "-")
291+
}
292+
}
293+
// [END android_compose_state_text_18]
294+
295+
296+
@Composable
297+
fun TextFieldOutputTransformation() {
298+
// [START android_compose_state_text_19]
299+
TextField(
300+
state = rememberTextFieldState(),
301+
outputTransformation = PhoneNumberOutputTransformation()
302+
)
303+
// [END android_compose_state_text_19]
304+
}

0 commit comments

Comments
 (0)