« Login UI in Android in Jetpack Compose

jetpack_compose_login_ui_screen.png

Create Sealed class InputType to tackel multiple types of inputs in 1 go

1sealed class InputType(
2 val label: String,
3 val icon: ImageVector,
4 val keyboardOptions: KeyboardOptions,
5 val visualTransformation: VisualTransformation
6) {
7 object Name : InputType(
8 label = "Username",
9 icon = Icons.Default.Person,
10 keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
11 visualTransformation = VisualTransformation.None
12 )
13
14 object Password : InputType(
15 label = "Password",
16 icon = Icons.Default.Lock,
17 keyboardOptions = KeyboardOptions(
18 imeAction = ImeAction.Done,
19 keyboardType = KeyboardType.Password
20 ),
21 visualTransformation = VisualTransformation.None
22 )
23}

Create generic type TextInput

1@Composable
2fun TextInput(
3 inputType: InputType,
4 focusRequester: FocusRequester? = null,
5 keyboardActions: KeyboardActions
6) {
7
8 var value by remember { mutableStateOf("") }
9
10 TextField(
11 value = value,
12 onValueChange = { value = it },
13 modifier = Modifier
14 .fillMaxWidth()
15 .focusOrder(focusRequester ?: FocusRequester()),
16 leadingIcon = { Icon(imageVector = inputType.icon, null) },
17 label = { Text(text = inputType.label) },
18 shape = Shapes.small,
19 colors = TextFieldDefaults.textFieldColors(
20 backgroundColor = Color.White,
21 focusedIndicatorColor = Color.Transparent,
22 unfocusedIndicatorColor = Color.Transparent,
23 disabledIndicatorColor = Color.Transparent
24 ),
25 singleLine = true,
26 keyboardOptions = inputType.keyboardOptions,
27 visualTransformation = inputType.visualTransformation,
28 keyboardActions = keyboardActions
29 )
30}

Create couple of extension functions on the Context object

1private fun Context.doLogin() {
2 Toast.makeText(
3 this,
4 "Something went wrong, try again later!",
5 Toast.LENGTH_SHORT
6 ).show()
7}
8
9private fun Context.buildExoPlayer(uri: Uri) =
10 ExoPlayer.Builder(this).build().apply {
11 setMediaItem(MediaItem.fromUri(uri))
12 repeatMode = Player.REPEAT_MODE_ALL
13 playWhenReady = true
14 prepare()
15 }
16
17private fun Context.buildPlayerView(exoPlayer: ExoPlayer) =
18 StyledPlayerView(this).apply {
19 player = exoPlayer
20 layoutParams = FrameLayout.LayoutParams(
21 ViewGroup.LayoutParams.MATCH_PARENT,
22 ViewGroup.LayoutParams.MATCH_PARENT
23 )
24 useController = false
25 resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
26 }

Final UI composable

1@Composable
2fun Login(videoUri: Uri) {
3 val context = LocalContext.current
4 val exoPlayer = remember { context.buildExoPlayer(videoUri) }
5 val passwordFocusRequester = FocusRequester()
6 val focusManager = LocalFocusManager.current
7
8 DisposableEffect(
9 AndroidView(factory = { it.buildPlayerView(exoPlayer) }, modifier = Modifier.fillMaxSize())
10 ) {
11 onDispose {
12 exoPlayer.release()
13 }
14 }
15
16 ProvideWindowInsets {
17 Column(
18 Modifier
19 .navigationBarsWithImePadding()
20 .padding(24.dp)
21 .fillMaxSize(),
22 verticalArrangement = Arrangement.spacedBy(16.dp, alignment = Alignment.Bottom),
23 horizontalAlignment = Alignment.CenterHorizontally
24 ) {
25
26 Icon(
27 painter = painterResource(id = R.drawable.logo),
28 contentDescription = null,
29 Modifier.size(80.dp),
30 tint = Color.White
31 )
32
33 TextInput(inputType = InputType.Name, keyboardActions = KeyboardActions(onNext = {
34 passwordFocusRequester.requestFocus()
35 }))
36
37 TextInput(inputType = InputType.Password, keyboardActions = KeyboardActions(onDone = {
38 focusManager.clearFocus()
39 context.doLogin()
40 }), focusRequester = passwordFocusRequester)
41
42 Button(onClick = {
43 context.doLogin()
44 }, modifier = Modifier.fillMaxWidth()) {
45 Text(text = "SIGN IN", Modifier.padding(vertical = 8.dp))
46 }
47
48 Divider(
49 color = Color.White.copy(alpha = 0.3f),
50 thickness = 1.dp,
51 modifier = Modifier.padding(top = 48.dp)
52 )
53
54 Row(verticalAlignment = Alignment.CenterVertically) {
55 Text(text = "Don't have and account", color = Color.White)
56 TextButton(onClick = {}) {
57 Text(text = "SIGN UP")
58 }
59 }
60 }
61 }
62}

For full working code please visit

https://github.com/anishakd4/JetpackLoginScreen