
Login screen ui in Jetpack Compose vs Flutter
Creating a Login Screen in Jetpack Compose
In this tutorial, we’ll create a simple login screen using Jetpack Compose in Kotlin. The screen will include a header image, a title, a login form, and a footer. Let’s break down each part of the code to understand how it works.
MainActivity Class
The MainActivity
class is the main entry point of our application. It sets up the content view with the login screen.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
LoginuicomposeTheme {
LoginScreen()
}
}
}
}
- ComponentActivity: A base class for activities that use Jetpack Compose.
- setContent: Sets the content view to the
LoginScreen
composable function within the theme.
LoginScreen Composable
The LoginScreen
function defines the structure of the login screen.
@Composable
fun LoginScreen() {
Box(
Modifier
.fillMaxSize()
.padding(0.dp)
.background(Color(0xF1F8F8F8))
) {
Box(
modifier = Modifier
.fillMaxSize()
.fillMaxHeight()
.padding(20.dp),
contentAlignment = Alignment.CenterStart,
) {
Column {
HeaderImageLogin(Modifier)
Spacer(modifier = Modifier.padding(15.dp))
TitleLogin()
Spacer(modifier = Modifier.padding(15.dp))
FormLogin()
Spacer(modifier = Modifier.padding(20.dp))
FooterLogin()
}
}
}
}
- Box: A container that allows for layering and positioning of child elements.
- Column: Arranges the child composables vertically.
- Spacer: Adds space between elements for better layout.
TitleLogin Composable
The TitleLogin
function displays the title of the login screen.
@Composable
fun TitleLogin() {
Text(
modifier = Modifier.fillMaxWidth(),
text = "LOG IN",
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
fontSize = 20.sp
)
}
- Text: Displays the text “LOG IN” with specified styling and alignment.
HeaderImageLogin Composable
The HeaderImageLogin
function displays an image at the top of the login screen.
@Composable
fun HeaderImageLogin(modifier: Modifier) {
Box(modifier = modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
Box(modifier = Modifier.size(150.dp)) {
Image(
painter = painterResource(id = R.drawable.logo),
contentDescription = "Header",
)
}
}
}
- Image: Loads and displays an image from resources.
- painterResource: Retrieves a drawable resource.
FooterLogin Composable
The FooterLogin
function displays a footer with a sign-up link.
@Composable
fun FooterLogin() {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
) {
Text(text = "Don't you have an account?")
TextButton(
modifier = Modifier.background(color = Color.Transparent),
onClick = {
// change route
}) {
Text(
text = "Sign up",
textDecoration = TextDecoration.Underline,
color = Color(0xFF5A67E4)
)
}
}
}
- Row: Arranges the child composables horizontally.
- TextButton: A button with text that can handle click events.
FormLogin Composable
The FormLogin
function defines the login form.
@Composable
fun FormLogin() {
Column {
UsernameField()
Spacer(modifier = Modifier.padding(18.dp))
PasswordField()
Spacer(modifier = Modifier.padding(18.dp))
ButtonLogin()
}
}
- Column: Arranges the form fields and button vertically.
- Spacer: Adds space between the form elements.
UsernameField Composable
The UsernameField
function defines a text field for entering the username.
@Composable
fun UsernameField() {
OutlinedTextField(
value = "",
onValueChange = {
// logic to change the value
},
shape = RoundedCornerShape(16.dp),
singleLine = true,
maxLines = 1,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(text = "Username")
},
colors = TextFieldDefaults.colors(
unfocusedContainerColor = Color.White,
focusedContainerColor = Color.White,
focusedLabelColor = Color(0xFF6977FF),
unfocusedIndicatorColor = Color(0xFFDFDFDF),
focusedIndicatorColor = Color(0xFFBBC1FF),
focusedLeadingIconColor = Color.Red
),
leadingIcon = {
Icon(
imageVector = Icons.Outlined.AccountCircle,
tint = Color(0xFFCECECE),
contentDescription = "Username"
)
}
)
}
- OutlinedTextField: A text field with an outlined border.
- keyboardOptions: Configures the keyboard input options.
- leadingIcon: Adds an icon inside the text field.
PasswordField Composable
The PasswordField
function defines a text field for entering the password.
@Composable
fun PasswordField() {
OutlinedTextField(
value = "",
onValueChange = {},
modifier = Modifier.fillMaxWidth(),
singleLine = true,
maxLines = 1,
shape = RoundedCornerShape(16.dp),
placeholder = {
Text(text = "Password")
},
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Text,
),
trailingIcon = {
IconButton(
onClick = {}
) {
Icon(
imageVector = Icons.Filled.Visibility, "Show Password",
tint = Color(0xFFB8B8B8)
)
}
},
colors = TextFieldDefaults.colors(
unfocusedContainerColor = Color.White,
focusedContainerColor = Color.White,
focusedLabelColor = Color(0xFF6977FF),
unfocusedIndicatorColor = Color(0xFFE7E7E7),
focusedIndicatorColor = Color(0xFFBBC1FF),
),
leadingIcon = {
Icon(
imageVector = Icons.Outlined.Key,
tint = Color(0xFFCECECE),
contentDescription = "Password"
)
}
)
}
- OutlinedTextField: A text field with an outlined border.
- keyboardOptions: Configures the keyboard input options.
- trailingIcon: Adds an icon inside the text field for showing/hiding the password.
ButtonLogin Composable
The ButtonLogin
function defines a button for submitting the login form.
@Composable
fun ButtonLogin() {
Button(
modifier = Modifier
.fillMaxWidth()
.height(48.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFFB40C47),
contentColor = Color(0xF1F1F1F1),
disabledContainerColor = Color(0xFFB40C47),
disabledContentColor = Color.White
),
onClick = {
// logic for login button
},
enabled = false,
shape = RoundedCornerShape(16.dp),
) {
Text(text = "Log In")
}
}