Table of contents
- Step 1: First after creating the project and building it, you can start with building some basic input screens for Username, Password, Login button, and Sign up button link.
- Step 2: To build the login screen here, Let's create some code for TextFields, and for text fields, we require Label, Icon, KeyboardOption & visualTransformation.
- Step 3: And now we create a Textfield which is taking the value of this class objects.
- Step 4: Now it's time to create LoginScreen with the inputs and buttons.
- Step 5: So it's time to add dependency
- Step 6: Add these 4 functions and it will help you to create an Exoplayer and show a toast when clicking on the Sign in button.
- Step 7: And the last step create a directory under res called "raw" and add a video to it.
Hello Coders, Hope you are coding well. Today I was just thinking about the topic for learning and I saw an app design with an elegant piece of layout with a video in the background and some fields for Registration, So I thought to create the same example with my "15 min Craft skill" 🤣. So Let's code.
In this tutorial, you'll learn how to create a sleek login screen using Jetpack Compose and Exoplayer. The guide walks you through setting up a new project, creating input fields for username and password, and adding a background video. You'll also find code snippets for building the login screen UI, handling user interactions, and integrating Exoplayer for the video background. By the end, you'll have a fully functional login screen with a modern design. Enjoy coding! 🥳
For this tutorial, I have developed this screen using Exoplayer, and Jetpack simple Login screen, So let me show you what I have done. If you have any questions please comment or you can reach me from any of the platforms. Click here and you will get all of my contacts.
First do create a new project, You all know how to create a new project for Jetpack Compose Right? Or just go here and you will find the steps to create one.
Step 1: First after creating the project and building it, you can start with building some basic input screens for Username, Password, Login button, and Sign up button link.
class MainActivity : ComponentActivity() {
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
Compose_chat_appTheme {
Scaffold(modifier = Modifier.fillMaxSize()) {
LoginScreen()
}
}
}
}
}
Step 2: To build the login screen here, Let's create some code for TextFields, and for text fields, we require Label, Icon, KeyboardOption & visualTransformation.
Label -> Using the label of the TextField
Icon -> Showing the leadingIcon from existing icons
keyboardOption -> to set imeAction for Next or Done keyboard actions
visualTransformation -> to set up the password text hide and username text visible
I have created a sealed class to create objects of particular one.
sealed class InputType(
val label: String,
val icon: ImageVector,
val keyboardOptions: KeyboardOptions,
val visualTransformation: VisualTransformation
) {
object UserName : InputType(
label = "Username",
icon = Icons.Default.Person,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
visualTransformation = VisualTransformation.None
)
object PassWord : InputType(
label = "Password", icon = Icons.Default.Lock, keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done, keyboardType = KeyboardType.Password
), visualTransformation = PasswordVisualTransformation()
)
}
Step 3: And now we create a Textfield which is taking the value of this class objects.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TextInput(
inputType: InputType,
focusRequester: FocusRequester? = null,
keyboardActions: KeyboardActions
) {
var value by remember { mutableStateOf("") }
TextField(
value = value,
onValueChange = { value = it },
modifier = Modifier
.fillMaxWidth()
.focusOrder(focusRequester ?: FocusRequester()),
leadingIcon = { Icon(imageVector = inputType.icon, null) },
label = { Text(text = inputType.label) },
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent
),
singleLine = true,
keyboardOptions = inputType.keyboardOptions,
visualTransformation = inputType.visualTransformation,
keyboardActions = keyboardActions
)
}
Step 4: Now it's time to create LoginScreen with the inputs and buttons.
@Composable
fun LoginScreen(videoUri: Uri) {
val context = LocalContext.current
val passwordFocusRequester = FocusRequester()
val focusManager = LocalFocusManager.current
val exoPlayer = remember { context.buildExoPlayer(videoUri) }
ProvideWindowInsets {
Column(
modifier = Modifier
.fillMaxSize()
.padding(25.dp),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painterResource(R.drawable.eclipse),
contentDescription = "",
modifier = Modifier.height(100.dp)
)
Text(
"Welcome to Eclipse", color = Color.Blue, style = TextStyle(
fontWeight = FontWeight.Bold, fontSize = 25.sp
)
)
Box(modifier = Modifier.padding(top = 10.dp))
TextInput(
InputType.UserName, keyboardActions = KeyboardActions(onNext = {
passwordFocusRequester.requestFocus()
})
)
Box(modifier = Modifier.padding(top = 10.dp))
TextInput(
InputType.PassWord, keyboardActions = KeyboardActions(onDone = {
focusManager.clearFocus()
}), focusRequester = passwordFocusRequester
)
Box(modifier = Modifier.padding(top = 10.dp))
Button(onClick = {
context.doLogin("Signin Button Clicked")
}, modifier = Modifier.fillMaxWidth()) {
Text(
"SIGN IN", modifier = Modifier.padding(vertical = 8.dp)
)
}
Divider(
color = Color.White.copy(alpha = 0.3f),
thickness = 1.dp,
modifier = Modifier.padding(top = 48.dp)
)
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Don't have an account?", color = Color.Blue)
TextButton(onClick = {}) {
Text("SING UP")
}
}
}
}
}
So our screen is ready now with the bottom aligned layout wrapped in a column with a logo, text, username, password, Sign In Button, and Sign up text.
Now let's work on the background video, and for that we have to use Exoplayer.
Step 5: So it's time to add dependency
implementation 'com.google.accompanist:accompanist-insets:0.23.1'
implementation 'com.google.android.exoplayer:exoplayer-core:2.17.1'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.17.1'
Add this to your app-level build.gradle file.
private fun getVideoUri(): Uri {
val rawId = resources.getIdentifier("tiny", "raw", packageName)
val videoUri = "android.resource://$packageName/$rawId"
return Uri.parse(videoUri)
}
private fun Context.doLogin(msg: String) {
Toast.makeText(
this, msg, Toast.LENGTH_SHORT
).show()
}
private fun Context.buildExoPlayer(uri: Uri) = ExoPlayer.Builder(this).build().apply {
setMediaItem(MediaItem.fromUri(uri))
repeatMode = Player.REPEAT_MODE_ALL
playWhenReady = true
prepare()
}
private fun Context.buildPlayerView(exoPlayer: ExoPlayer) = StyledPlayerView(this).apply {
player = exoPlayer
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
useController = false
resizeMode = RESIZE_MODE_ZOOM
}
Step 6: Add these 4 functions and it will help you to create an Exoplayer and show a toast when clicking on the Sign in button.
Now pass the getVideoUri() in the LoginScreen composable function and add the below code in it. Now the final code for LoginScreen is as below.
@Composable
fun LoginScreen(videoUri: Uri) {
val context = LocalContext.current
val passwordFocusRequester = FocusRequester()
val focusManager = LocalFocusManager.current
val exoPlayer = remember { context.buildExoPlayer(videoUri) }
DisposableEffect(
AndroidView(
factory = { it.buildPlayerView(exoPlayer) }, modifier = Modifier.fillMaxSize()
)
) {
onDispose {
exoPlayer.release()
}
}
ProvideWindowInsets {
Column(
modifier = Modifier
.fillMaxSize()
.padding(25.dp),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painterResource(R.drawable.eclipse),
contentDescription = "",
modifier = Modifier.height(100.dp)
)
Text(
"Welcome to Eclipse", color = Color.Blue, style = TextStyle(
fontWeight = FontWeight.Bold, fontSize = 25.sp
)
)
Box(modifier = Modifier.padding(top = 10.dp))
TextInput(
InputType.UserName, keyboardActions = KeyboardActions(onNext = {
passwordFocusRequester.requestFocus()
})
)
Box(modifier = Modifier.padding(top = 10.dp))
TextInput(
InputType.PassWord, keyboardActions = KeyboardActions(onDone = {
focusManager.clearFocus()
}), focusRequester = passwordFocusRequester
)
Box(modifier = Modifier.padding(top = 10.dp))
Button(onClick = {
context.doLogin("Signin Button Clicked")
}, modifier = Modifier.fillMaxWidth()) {
Text(
"SIGN IN", modifier = Modifier.padding(vertical = 8.dp)
)
}
Divider(
color = Color.White.copy(alpha = 0.3f),
thickness = 1.dp,
modifier = Modifier.padding(top = 48.dp)
)
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Don't have an account?", color = Color.Blue)
TextButton(onClick = {}) {
Text("SING UP")
}
}
}
}
}
Step 7: And the last step create a directory under res called "raw" and add a video to it.
and you are all set.
Enjoy the amazing login screen 🥳