Fiddling with the login and signup screens
This commit is contained in:
parent
ecea0e12d6
commit
45d632f786
7 changed files with 180 additions and 35 deletions
|
@ -64,6 +64,8 @@ dependencies {
|
|||
implementation(libs.androidx.ui.graphics)
|
||||
implementation(libs.androidx.ui.tooling.preview)
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
||||
implementation(libs.lifecycle.runtime.compose)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.DebtPirate"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/Theme.DebtPirate">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.DebtPirate">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.DebtPirate"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -4,12 +4,14 @@ import android.os.Bundle
|
|||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import kotlinx.serialization.Serializable
|
||||
import software.makeshift.debtpirate.ui.theme.DebtPirateTheme
|
||||
import software.makeshift.debtpirate.usecases.login.LoginScreen
|
||||
import software.makeshift.debtpirate.usecases.login.LoginScreenViewModel
|
||||
|
||||
@Serializable
|
||||
object LoginRoute
|
||||
|
@ -24,7 +26,11 @@ class MainActivity : ComponentActivity() {
|
|||
DebtPirateTheme {
|
||||
NavHost(navController = navController, startDestination = LoginRoute) {
|
||||
composable<LoginRoute> {
|
||||
LoginScreen()
|
||||
val viewModel: LoginScreenViewModel by viewModels()
|
||||
LoginScreen(
|
||||
viewModel.loginState,
|
||||
viewModel::updateLoginUsername
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,123 @@
|
|||
@file:OptIn(ExperimentalMaterial3Api::class)
|
||||
|
||||
package software.makeshift.debtpirate.usecases.login
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SecondaryTabRow
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import software.makeshift.debtpirate.R
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun LoginScreen() {
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||
Greeting(modifier = Modifier.padding(innerPadding))
|
||||
fun LoginScreen(
|
||||
loginState: StateFlow<LoginState>,
|
||||
updateLoginUsername: (String) -> Unit
|
||||
) {
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) {
|
||||
Column {
|
||||
Banner(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
)
|
||||
|
||||
LoginAndSignUpForms(
|
||||
loginState,
|
||||
modifier = Modifier
|
||||
.weight(3f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Greeting(modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = "Hello from Login!",
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
private fun Banner(modifier: Modifier = Modifier) {
|
||||
Box(modifier = modifier.background(Color.Green)) {
|
||||
Text(
|
||||
text = "Hello from Login! I'm in a box!",
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LoginAndSignUpForms(
|
||||
loginTabState: StateFlow<LoginState>,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
val pagerState = rememberPagerState(initialPage = 0) { 2 }
|
||||
|
||||
SecondaryTabRow(
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
modifier = Modifier.height(48.dp)
|
||||
) {
|
||||
val tabTextStyle = MaterialTheme.typography.titleLarge
|
||||
Tab(
|
||||
selected = pagerState.currentPage == 0,
|
||||
onClick = { pagerState.requestScrollToPage(0) },
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.loginscreen_logintab_logintitle),
|
||||
style = tabTextStyle,
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
)
|
||||
}
|
||||
Tab(
|
||||
selected = pagerState.currentPage == 1,
|
||||
onClick = { pagerState.requestScrollToPage(1) },
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.loginscreen_logintab_signuptitle),
|
||||
style = tabTextStyle,
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
userScrollEnabled = false,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) { page ->
|
||||
when (page) {
|
||||
0 -> {
|
||||
Text("Page 1!")
|
||||
}
|
||||
|
||||
1 -> {
|
||||
Text("Page 2!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//@Composable
|
||||
//private fun LoginForm(state: StateFlow<LoginState>, onUsernameUpdate: (String) -> Unit, onPasswordUpdate: (String) -> Unit) {
|
||||
// Column {
|
||||
// OutlinedTextField(value = , onValueChange = )
|
||||
// }
|
||||
//}
|
|
@ -0,0 +1,32 @@
|
|||
package software.makeshift.debtpirate.usecases.login
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
data class LoginState(val username: String? = null, val password: String? = null)
|
||||
|
||||
data class SignUpState(
|
||||
val username: String? = null,
|
||||
val password: String? = null,
|
||||
val passwordConfirmed: String? = null,
|
||||
val email: String? = null
|
||||
)
|
||||
|
||||
class LoginScreenViewModel : ViewModel() {
|
||||
private val _loginState = MutableStateFlow(LoginState())
|
||||
val loginState = _loginState.asStateFlow()
|
||||
|
||||
val loginUsername: Flow<String?>
|
||||
get() = loginState.map { loginState -> loginState.username }
|
||||
|
||||
fun updateLoginUsername(username: String) {
|
||||
_loginState.update { state ->
|
||||
val (_, password) = state
|
||||
LoginState(username, password)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
<resources>
|
||||
<string name="app_name">Debt Pirate</string>
|
||||
<string name="title_activity_main">MainActivity</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="loginscreen_logintab_logintitle">Login</string>
|
||||
<string name="loginscreen_logintab_signuptitle">Sign Up</string>
|
||||
</resources>
|
|
@ -9,6 +9,8 @@ appcompat = "1.7.0"
|
|||
material = "1.12.0"
|
||||
material3 = "1.3.0-beta05"
|
||||
kotlinxSerializationJson = "1.7.1"
|
||||
lifecycleRuntimeCompose = "2.8.4"
|
||||
lifecycleViewmodelCompose = "2.8.4"
|
||||
lifecycleRuntimeKtx = "2.8.4"
|
||||
activityCompose = "1.9.1"
|
||||
composeBom = "2024.06.00"
|
||||
|
@ -23,6 +25,8 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version
|
|||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||
material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
|
||||
kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
|
||||
lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycleRuntimeCompose" }
|
||||
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycleViewmodelCompose" }
|
||||
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
||||
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
||||
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
||||
|
|
Loading…
Add table
Reference in a new issue