Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Key board #22

Open
wants to merge 5 commits into
base: #1_composable_function_info
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# JetPackCompose Basic

In this project, you will know how to open keyboard at screen start-up and get focus on TextField.

First know this,

➡ FocusRequester:
The FocusRequester is used in conjunction with Modifier.focusRequester to send requests to change focus.

➡ SoftwareKeyboardController:
SoftwareKeyboardController that can control the current software keyboard.

Steps:
1. Initialize FocusRequester and SoftwareKeyboardController
val keyboard = LocalSoftwareKeyboardController.current
val focusRequester = remember { FocusRequester() }

2. Call requestFocus() method to get focus and show the keyboard and put all this code inside LanchedEffect to run at once
LaunchedEffect(Unit) {
focusRequester.requestFocus()
keyboard?.show()
}
3. Add focusRequester modifier and pass focusRequester of the TextField
TextField(Modifier.focusRequester(focusRequester),..)

4. Add a keyboard Options as Done and Action to hide keyboard when submit input.

keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
keyboard?.hide()
})

# Video
https://github.com/KaushalVasava/JetPackCompose_Basic/assets/49050597/97046668-2033-4c53-b374-da35b5ead465

# Author
Kaushal Vasava

24 changes: 12 additions & 12 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ plugins {

android {
namespace 'com.lahsuak.apps.jetpackcomposebasic'
compileSdk 33
compileSdk 34

defaultConfig {
applicationId "com.lahsuak.apps.jetpackcomposebasic"
minSdk 23
targetSdk 33
targetSdk 34
versionCode 1
versionName "1.0"

Expand All @@ -27,17 +27,17 @@ android {
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.1.1'
kotlinCompilerExtensionVersion '1.4.7'
}
packagingOptions {
resources {
Expand All @@ -48,15 +48,15 @@ android {

dependencies {

implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.activity:activity-compose:1.6.1'
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.activity:activity-compose:1.7.2'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.compose.material3:material3:1.1.0-alpha03'
implementation 'androidx.compose.material3:material3:1.2.0-alpha03'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,36 @@ package com.lahsuak.apps.jetpackcomposebasic
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.lahsuak.apps.jetpackcomposebasic.ui.screen.SplashScreen
import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme

class MainActivity : ComponentActivity() {
Expand All @@ -22,29 +45,56 @@ class MainActivity : ComponentActivity() {
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
LoginScreen()
}
}
}
}
}
/***
Composable functions :
A composable function is a regular function annotated with @Composable.
This enables your function to call other @Composable functions within it.
You can see how the Greeting function is marked as @Composable.
This function will produce a piece of UI hierarchy displaying the given input,
String. Text is a composable function provided by the library.
***/

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
fun LoginScreen() {
val keyboard = LocalSoftwareKeyboardController.current
val focusRequester = remember { FocusRequester() }

LaunchedEffect(Unit) {
// requesting to get focus
focusRequester.requestFocus()
// show keyboard at start-up
keyboard?.show()
}
var name by rememberSaveable {
mutableStateOf("")
}

Column(Modifier.fillMaxSize().padding(16.dp)) {
OutlinedTextField(
value = name,
onValueChange = {
name = it
},
placeholder = {
Text("Enter your name")
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
// hide keyboard when submit input
keyboard?.hide()
}),
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester) // add focusRequester to get focus on textfield
.background(MaterialTheme.colorScheme.surfaceVariant),
)
}
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
JetPackComposeBasicTheme {
Greeting("Android")
LoginScreen()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package com.lahsuak.apps.jetpackcomposebasic.ui.screen

Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.lahsuak.apps.jetpackcomposebasic.ui.screen

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.LocationOn
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.Button
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.lahsuak.apps.jetpackcomposebasic.R

@Composable
fun SplashScreen() {
Box(Modifier.fillMaxSize()) {
Column(
Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
) {
Text(
"Annpurna",
fontSize = 20.sp,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(16.dp))
Image(
painter = painterResource(id = R.drawable.food_logo), contentDescription = "food",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(300.dp)
.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(16.dp))
Text(
"A good food make your life healthier",
fontSize = 32.sp,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.onSurface,
textAlign = TextAlign.Center,
fontFamily = FontFamily.Serif,
letterSpacing = 2.sp,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(16.dp))
FilledTonalButton(
onClick = {},
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
Icon(Icons.Default.LocationOn, contentDescription = null)
Spacer(modifier = Modifier.width(4.dp))
Text("Choose language")
}
Spacer(modifier = Modifier.height(16.dp))
Text(
"Login or registration",
fontSize = 16.sp,
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(8.dp))
FilledTonalButton(
onClick = { /*TODO*/ },
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
Icon(Icons.Default.Person, contentDescription = null)
Spacer(modifier = Modifier.width(4.dp))
Text("Google SignIn")
}
Spacer(modifier = Modifier.height(16.dp))
Text("OR", Modifier.align(Alignment.CenterHorizontally))
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { /*TODO*/ }, Modifier.fillMaxWidth()) {
Text("Login")
}
}
}
}

@Preview(showBackground = true)
@Composable
fun PreviewSplashScreen() {
MaterialTheme {
Surface(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
SplashScreen()
}
}
}
Binary file added app/src/main/res/drawable/food_logo.webp
Binary file not shown.
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
buildscript {
ext {
compose_version = '1.3.2'
compose_version = '1.4.7'
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.3.0' apply false
id 'com.android.library' version '7.3.0' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
id 'com.android.application' version '8.1.0' apply false
id 'com.android.library' version '8.1.0' apply false
id 'org.jetbrains.kotlin.android' version '1.8.21' apply false
}