Migrate UI to Jetpack Compose
This commit is contained in:
parent
c2579f8765
commit
48923fa892
@ -33,15 +33,32 @@ android {
|
|||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "1.8"
|
jvmTarget = "1.8"
|
||||||
}
|
}
|
||||||
|
buildFeatures {
|
||||||
|
compose = true
|
||||||
|
}
|
||||||
|
composeOptions {
|
||||||
|
kotlinCompilerExtensionVersion = "1.5.10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation("androidx.core:core-ktx:1.12.0")
|
implementation("androidx.core:core-ktx:1.12.0")
|
||||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
|
||||||
implementation("com.google.android.material:material:1.11.0")
|
implementation("com.google.android.material:material:1.11.0")
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
|
||||||
|
val composeBom = platform("androidx.compose:compose-bom:2024.02.01")
|
||||||
|
implementation(composeBom)
|
||||||
|
implementation("androidx.compose.ui:ui")
|
||||||
|
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||||
|
implementation("androidx.compose.material3:material3")
|
||||||
|
implementation("androidx.activity:activity-compose:1.8.2")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
|
||||||
|
|
||||||
|
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||||
|
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||||
|
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
androidTestImplementation(composeBom)
|
||||||
|
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||||
}
|
}
|
||||||
@ -3,88 +3,296 @@ package cz.bugsy.passwordzebra
|
|||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Button
|
import androidx.activity.ComponentActivity
|
||||||
import android.widget.TextView
|
import androidx.activity.compose.setContent
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.compose.foundation.border
|
||||||
private const val KEY_PASSWORD = "password"
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
class MainActivity : AppCompatActivity() {
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
private lateinit var generateButton: Button
|
import androidx.compose.foundation.layout.Row
|
||||||
private lateinit var passwordTextView: TextView
|
import androidx.compose.foundation.layout.Spacer
|
||||||
private lateinit var switchWithoutSpaces: com.google.android.material.switchmaterial.SwitchMaterial
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
private lateinit var switchSpecialChars: com.google.android.material.switchmaterial.SwitchMaterial
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
private lateinit var passwordLengthPicker: android.widget.NumberPicker
|
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.foundation.layout.widthIn
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.FilledIconButton
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Switch
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import cz.bugsy.passwordzebra.ui.components.NumberPickerView
|
||||||
|
import cz.bugsy.passwordzebra.ui.theme.PasswordZebraTheme
|
||||||
|
|
||||||
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
enableEdgeToEdge()
|
||||||
|
setContent {
|
||||||
generateButton = findViewById(R.id.generateButton)
|
PasswordZebraTheme {
|
||||||
passwordTextView = findViewById(R.id.passwordTextView)
|
PasswordZebraApp()
|
||||||
switchWithoutSpaces = findViewById(R.id.switchWithoutSpaces)
|
|
||||||
switchSpecialChars = findViewById(R.id.switchSpecialChars)
|
|
||||||
passwordLengthPicker = findViewById(R.id.passwordLengthPicker)
|
|
||||||
|
|
||||||
// Set the range of selectable values for password length (1 to 10)
|
|
||||||
val defaultPasswordLength = 4
|
|
||||||
passwordLengthPicker.minValue = 1
|
|
||||||
passwordLengthPicker.maxValue = 10
|
|
||||||
passwordLengthPicker.value = defaultPasswordLength
|
|
||||||
|
|
||||||
generateButton.setOnClickListener {
|
|
||||||
generatePassword()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore password after rotation, otherwise generate a new one
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
passwordTextView.text = savedInstanceState.getString(KEY_PASSWORD, "")
|
|
||||||
} else {
|
|
||||||
generatePassword()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set click listener to copy password to clipboard
|
|
||||||
passwordTextView.setOnClickListener {
|
|
||||||
copyToClipboard(passwordTextView.text.toString(), getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
|
||||||
super.onSaveInstanceState(outState)
|
|
||||||
outState.putString(KEY_PASSWORD, passwordTextView.text.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generatePassword() {
|
|
||||||
val passwordLength = passwordLengthPicker.value
|
|
||||||
val password = generateRandomWords(passwordLength)
|
|
||||||
passwordTextView.text = password
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateRandomWords(numWords: Int): String {
|
|
||||||
return buildString {
|
|
||||||
repeat(numWords) {
|
|
||||||
append(PasswordGenerator.generateRandomWord())
|
|
||||||
append(" ") // Add space between words
|
|
||||||
}
|
}
|
||||||
}.let { password ->
|
|
||||||
// Check if the switch for adding special characters is checked
|
|
||||||
if (switchSpecialChars.isChecked) {
|
|
||||||
PasswordGenerator.addSpecialCharacters(password)
|
|
||||||
} else {
|
|
||||||
password
|
|
||||||
}
|
|
||||||
}.trim() // Remove trailing space
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun copyToClipboard(text: String, clipboardManager: ClipboardManager) {
|
|
||||||
val clipData = if (switchWithoutSpaces.isChecked) {
|
|
||||||
val textNoSpaces = text.filter { !it.isWhitespace() }
|
|
||||||
ClipData.newPlainText("Password", textNoSpaces)
|
|
||||||
} else {
|
|
||||||
ClipData.newPlainText("Password", text)
|
|
||||||
}
|
}
|
||||||
clipboardManager.setPrimaryClip(clipData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PasswordZebraApp() {
|
||||||
|
var password by rememberSaveable { mutableStateOf("") }
|
||||||
|
var wordCount by rememberSaveable { mutableIntStateOf(4) }
|
||||||
|
var withoutSpaces by rememberSaveable { mutableStateOf(false) }
|
||||||
|
var addSpecialChars by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
if (password.isEmpty()) {
|
||||||
|
password = generatePassword(wordCount, addSpecialChars)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val onGenerate = { password = generatePassword(wordCount, addSpecialChars) }
|
||||||
|
val isLandscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
|
||||||
|
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||||
|
if (isLandscape) {
|
||||||
|
// Landscape: controls left (vertically centered), password + generate button right
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(innerPadding)
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
) {
|
||||||
|
// Left: controls only, vertically centered
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
ControlsPanel(
|
||||||
|
wordCount = wordCount,
|
||||||
|
withoutSpaces = withoutSpaces,
|
||||||
|
addSpecialChars = addSpecialChars,
|
||||||
|
onWordCountChange = { wordCount = it },
|
||||||
|
onWithoutSpacesChange = { withoutSpaces = it },
|
||||||
|
onAddSpecialCharsChange = { addSpecialChars = it },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Right: password box fills remaining height, generate button pinned to bottom
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
PasswordBox(
|
||||||
|
password = password,
|
||||||
|
onClick = { copyToClipboard(context, password, withoutSpaces) },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f),
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
GenerateButton(onClick = onGenerate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Portrait: password box top, controls middle, generate button pinned to bottom
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(innerPadding)
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
PasswordBox(
|
||||||
|
password = password,
|
||||||
|
onClick = { copyToClipboard(context, password, withoutSpaces) },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(150.dp),
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.weight(2f))
|
||||||
|
ControlsPanel(
|
||||||
|
wordCount = wordCount,
|
||||||
|
withoutSpaces = withoutSpaces,
|
||||||
|
addSpecialChars = addSpecialChars,
|
||||||
|
onWordCountChange = { wordCount = it },
|
||||||
|
onWithoutSpacesChange = { withoutSpaces = it },
|
||||||
|
onAddSpecialCharsChange = { addSpecialChars = it },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.weight(3f))
|
||||||
|
GenerateButton(onClick = onGenerate)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PasswordBox(password: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.border(
|
||||||
|
width = 2.dp,
|
||||||
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
shape = RoundedCornerShape(12.dp),
|
||||||
|
)
|
||||||
|
.clickable { onClick() }
|
||||||
|
.padding(16.dp),
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = password,
|
||||||
|
fontSize = 24.sp,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ControlsPanel(
|
||||||
|
wordCount: Int,
|
||||||
|
withoutSpaces: Boolean,
|
||||||
|
addSpecialChars: Boolean,
|
||||||
|
onWordCountChange: (Int) -> Unit,
|
||||||
|
onWithoutSpacesChange: (Boolean) -> Unit,
|
||||||
|
onAddSpecialCharsChange: (Boolean) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.pw_straighten),
|
||||||
|
contentDescription = stringResource(R.string.image_length_desc),
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.textview_password_length),
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
NumberPickerView(
|
||||||
|
value = wordCount,
|
||||||
|
minValue = 1,
|
||||||
|
maxValue = 10,
|
||||||
|
onValueChange = onWordCountChange,
|
||||||
|
modifier = Modifier.widthIn(min = 80.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.pw_letter_spacing),
|
||||||
|
contentDescription = stringResource(R.string.image_wospaces),
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.switch_without_spaces),
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
Switch(
|
||||||
|
checked = withoutSpaces,
|
||||||
|
onCheckedChange = onWithoutSpacesChange,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.pw_special_character),
|
||||||
|
contentDescription = stringResource(R.string.image_specialchars),
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.switch_special_characters),
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
Switch(
|
||||||
|
checked = addSpecialChars,
|
||||||
|
onCheckedChange = onAddSpecialCharsChange,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun GenerateButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
|
FilledIconButton(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = modifier.size(60.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.pw_generate),
|
||||||
|
contentDescription = stringResource(R.string.button_generate_description),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generatePassword(wordCount: Int, addSpecialChars: Boolean): String {
|
||||||
|
return buildString {
|
||||||
|
repeat(wordCount) {
|
||||||
|
append(PasswordGenerator.generateRandomWord())
|
||||||
|
append(" ")
|
||||||
|
}
|
||||||
|
}.let { password ->
|
||||||
|
if (addSpecialChars) {
|
||||||
|
PasswordGenerator.addSpecialCharacters(password)
|
||||||
|
} else {
|
||||||
|
password
|
||||||
|
}
|
||||||
|
}.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun copyToClipboard(context: Context, text: String, withoutSpaces: Boolean) {
|
||||||
|
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
val clipText = if (withoutSpaces) text.filter { !it.isWhitespace() } else text
|
||||||
|
val clipData = ClipData.newPlainText("Password", clipText)
|
||||||
|
clipboardManager.setPrimaryClip(clipData)
|
||||||
|
}
|
||||||
|
|||||||
@ -2,16 +2,10 @@ package cz.bugsy.passwordzebra
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import com.google.android.material.color.DynamicColors
|
import com.google.android.material.color.DynamicColors
|
||||||
import com.google.android.material.color.DynamicColorsOptions
|
|
||||||
|
|
||||||
class PasswordZebra : Application() {
|
class PasswordZebra : Application() {
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
// Apply dynamic color
|
super.onCreate()
|
||||||
DynamicColors.applyToActivitiesIfAvailable(
|
DynamicColors.applyToActivitiesIfAvailable(this)
|
||||||
this,
|
|
||||||
DynamicColorsOptions.Builder()
|
|
||||||
.setThemeOverlay(R.style.AppTheme_Overlay)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
package cz.bugsy.passwordzebra.ui.components
|
||||||
|
|
||||||
|
import android.widget.NumberPicker
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun NumberPickerView(
|
||||||
|
value: Int,
|
||||||
|
minValue: Int,
|
||||||
|
maxValue: Int,
|
||||||
|
onValueChange: (Int) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
AndroidView(
|
||||||
|
factory = { ctx ->
|
||||||
|
NumberPicker(ctx).apply {
|
||||||
|
this.minValue = minValue
|
||||||
|
this.maxValue = maxValue
|
||||||
|
this.value = value
|
||||||
|
setOnValueChangedListener { _, _, new -> onValueChange(new) }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update = { picker ->
|
||||||
|
if (picker.value != value) picker.value = value
|
||||||
|
},
|
||||||
|
modifier = modifier,
|
||||||
|
)
|
||||||
|
}
|
||||||
92
app/src/main/java/cz/bugsy/passwordzebra/ui/theme/Theme.kt
Normal file
92
app/src/main/java/cz/bugsy/passwordzebra/ui/theme/Theme.kt
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package cz.bugsy.passwordzebra.ui.theme
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.darkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicDarkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicLightColorScheme
|
||||||
|
import androidx.compose.material3.lightColorScheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
|
||||||
|
private val LightColorScheme = lightColorScheme(
|
||||||
|
primary = Color(0xFF286C2A),
|
||||||
|
onPrimary = Color(0xFFFFFFFF),
|
||||||
|
primaryContainer = Color(0xFFABF5A3),
|
||||||
|
onPrimaryContainer = Color(0xFF002203),
|
||||||
|
secondary = Color(0xFF00639A),
|
||||||
|
onSecondary = Color(0xFFFFFFFF),
|
||||||
|
secondaryContainer = Color(0xFFCEE5FF),
|
||||||
|
onSecondaryContainer = Color(0xFF001D32),
|
||||||
|
tertiary = Color(0xFF38656A),
|
||||||
|
onTertiary = Color(0xFFFFFFFF),
|
||||||
|
tertiaryContainer = Color(0xFFBCEBF0),
|
||||||
|
onTertiaryContainer = Color(0xFF002023),
|
||||||
|
error = Color(0xFFBA1A1A),
|
||||||
|
errorContainer = Color(0xFFFFDAD6),
|
||||||
|
onError = Color(0xFFFFFFFF),
|
||||||
|
onErrorContainer = Color(0xFF410002),
|
||||||
|
background = Color(0xFFFCFDF6),
|
||||||
|
onBackground = Color(0xFF1A1C19),
|
||||||
|
surface = Color(0xFFFCFDF6),
|
||||||
|
onSurface = Color(0xFF1A1C19),
|
||||||
|
surfaceVariant = Color(0xFFDEE5D8),
|
||||||
|
onSurfaceVariant = Color(0xFF424940),
|
||||||
|
outline = Color(0xFF72796F),
|
||||||
|
inverseOnSurface = Color(0xFFF1F1EB),
|
||||||
|
inverseSurface = Color(0xFF2F312D),
|
||||||
|
inversePrimary = Color(0xFF90D889),
|
||||||
|
surfaceTint = Color(0xFF286C2A),
|
||||||
|
outlineVariant = Color(0xFFC2C9BD),
|
||||||
|
scrim = Color(0xFF000000),
|
||||||
|
)
|
||||||
|
|
||||||
|
private val DarkColorScheme = darkColorScheme(
|
||||||
|
primary = Color(0xFF90D889),
|
||||||
|
onPrimary = Color(0xFF003909),
|
||||||
|
primaryContainer = Color(0xFF085314),
|
||||||
|
onPrimaryContainer = Color(0xFFABF5A3),
|
||||||
|
secondary = Color(0xFF96CCFF),
|
||||||
|
onSecondary = Color(0xFF003353),
|
||||||
|
secondaryContainer = Color(0xFF004A75),
|
||||||
|
onSecondaryContainer = Color(0xFFCEE5FF),
|
||||||
|
tertiary = Color(0xFFA0CFD4),
|
||||||
|
onTertiary = Color(0xFF00363B),
|
||||||
|
tertiaryContainer = Color(0xFF1E4D52),
|
||||||
|
onTertiaryContainer = Color(0xFFBCEBF0),
|
||||||
|
error = Color(0xFFFFB4AB),
|
||||||
|
errorContainer = Color(0xFF93000A),
|
||||||
|
onError = Color(0xFF690005),
|
||||||
|
onErrorContainer = Color(0xFFFFDAD6),
|
||||||
|
background = Color(0xFF1A1C19),
|
||||||
|
onBackground = Color(0xFFE2E3DD),
|
||||||
|
surface = Color(0xFF1A1C19),
|
||||||
|
onSurface = Color(0xFFE2E3DD),
|
||||||
|
surfaceVariant = Color(0xFF424940),
|
||||||
|
onSurfaceVariant = Color(0xFFC2C9BD),
|
||||||
|
outline = Color(0xFF8C9388),
|
||||||
|
inverseOnSurface = Color(0xFF1A1C19),
|
||||||
|
inverseSurface = Color(0xFFE2E3DD),
|
||||||
|
inversePrimary = Color(0xFF286C2A),
|
||||||
|
surfaceTint = Color(0xFF90D889),
|
||||||
|
outlineVariant = Color(0xFF424940),
|
||||||
|
scrim = Color(0xFF000000),
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PasswordZebraTheme(
|
||||||
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
|
content: @Composable () -> Unit,
|
||||||
|
) {
|
||||||
|
val colorScheme = when {
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||||
|
val ctx = LocalContext.current
|
||||||
|
if (darkTheme) dynamicDarkColorScheme(ctx) else dynamicLightColorScheme(ctx)
|
||||||
|
}
|
||||||
|
darkTheme -> DarkColorScheme
|
||||||
|
else -> LightColorScheme
|
||||||
|
}
|
||||||
|
MaterialTheme(colorScheme = colorScheme, content = content)
|
||||||
|
}
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
<solid android:color="@android:color/transparent" />
|
|
||||||
<stroke android:width="1dip" android:color="@color/material_dynamic_primary80"/>
|
|
||||||
<corners android:radius="8dp" />
|
|
||||||
</shape>
|
|
||||||
@ -1,167 +0,0 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".MainActivity"
|
|
||||||
>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordTextView"
|
|
||||||
android:layout_width="335dp"
|
|
||||||
android:layout_height="149dp"
|
|
||||||
android:layout_centerHorizontal="false"
|
|
||||||
android:layout_marginHorizontal="10dp"
|
|
||||||
android:layout_marginTop="20dp"
|
|
||||||
android:background="@drawable/password_background"
|
|
||||||
android:gravity="center"
|
|
||||||
android:minHeight="150dp"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:text=""
|
|
||||||
android:textSize="24sp"
|
|
||||||
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/generateButton"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/passwordLengthPicker"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_bias="0.0" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordLengthLabel"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="0dp"
|
|
||||||
android:text="@string/textview_password_length"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/passwordLengthPicker"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/guideline4"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/passwordLengthPicker" />
|
|
||||||
|
|
||||||
<NumberPicker
|
|
||||||
android:id="@+id/passwordLengthPicker"
|
|
||||||
android:layout_width="69dp"
|
|
||||||
android:layout_height="178dp"
|
|
||||||
android:layout_marginStart="81dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/switchWithoutSpaces"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/guideline5"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/passwordLengthLabel"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_bias="1.0" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/switchWithoutSpaces"
|
|
||||||
style="@style/Widget.Material3.CompoundButton.MaterialSwitch"
|
|
||||||
android:layout_width="299dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:text="@string/switch_without_spaces"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/switchSpecialChars"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/guideline5"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/guideline4" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/switchSpecialChars"
|
|
||||||
style="@style/Widget.Material3.CompoundButton.MaterialSwitch"
|
|
||||||
android:layout_width="299dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginBottom="36dp"
|
|
||||||
android:text="@string/switch_special_characters"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/guideline5"
|
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/guideline4" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/generateButton"
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_gravity="end|bottom"
|
|
||||||
android:layout_marginBottom="48dp"
|
|
||||||
android:contentDescription="@string/button_generate_description"
|
|
||||||
android:insetLeft="0dp"
|
|
||||||
android:insetTop="0dp"
|
|
||||||
android:insetRight="0dp"
|
|
||||||
android:insetBottom="0dp"
|
|
||||||
android:padding="0dp"
|
|
||||||
android:tooltipText="@string/button_generate_text"
|
|
||||||
app:backgroundColor="@color/design_default_color_primary"
|
|
||||||
app:cornerRadius="16dp"
|
|
||||||
app:icon="@drawable/pw_generate"
|
|
||||||
app:iconGravity="textTop"
|
|
||||||
app:iconPadding="0dp"
|
|
||||||
app:iconSize="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/passwordLengthPicker"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/guideline5" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
app:layout_constraintGuide_begin="20dp" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageViewPwLength"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:contentDescription="@string/image_length_desc"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/passwordLengthLabel"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/passwordLengthLabel"
|
|
||||||
app:layout_constraintVertical_bias="0.0"
|
|
||||||
app:srcCompat="@drawable/pw_straighten" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageViewWithoutSpaces"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
android:layout_marginBottom="9dp"
|
|
||||||
android:contentDescription="@string/image_wospaces"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/switchWithoutSpaces"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/switchWithoutSpaces"
|
|
||||||
app:layout_constraintVertical_bias="0.8"
|
|
||||||
app:srcCompat="@drawable/pw_letter_spacing" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageViewAddSpecialChars"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:contentDescription="@string/image_specialchars"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/switchSpecialChars"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/switchSpecialChars"
|
|
||||||
app:layout_constraintVertical_bias="0.625"
|
|
||||||
app:srcCompat="@drawable/pw_special_character" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline3"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_begin="16dp" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline4"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_begin="65dp" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline5"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_begin="365dp" />
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@ -1,161 +0,0 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".MainActivity"
|
|
||||||
>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordTextView"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginHorizontal="10dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:background="@drawable/password_background"
|
|
||||||
android:gravity="center"
|
|
||||||
android:minHeight="150dp"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:text=""
|
|
||||||
android:textSize="24sp"
|
|
||||||
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordLengthLabel"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="0dp"
|
|
||||||
android:text="@string/textview_password_length"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/passwordLengthPicker"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/guideline4"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/passwordLengthPicker" />
|
|
||||||
|
|
||||||
<NumberPicker
|
|
||||||
android:id="@+id/passwordLengthPicker"
|
|
||||||
android:layout_width="69dp"
|
|
||||||
android:layout_height="178dp"
|
|
||||||
android:layout_marginStart="81dp"
|
|
||||||
android:layout_marginEnd="0dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/switchWithoutSpaces"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/guideline5"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/passwordLengthLabel"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_bias="1.0" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/switchWithoutSpaces"
|
|
||||||
android:layout_width="299dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:text="@string/switch_without_spaces"
|
|
||||||
style="@style/Widget.Material3.CompoundButton.MaterialSwitch"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/switchSpecialChars"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/guideline4" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/switchSpecialChars"
|
|
||||||
android:layout_width="299dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginBottom="36dp"
|
|
||||||
android:text="@string/switch_special_characters"
|
|
||||||
style="@style/Widget.Material3.CompoundButton.MaterialSwitch"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/generateButton"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/guideline4" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/generateButton"
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_gravity="end|bottom"
|
|
||||||
app:iconGravity="textTop"
|
|
||||||
android:padding="0dp"
|
|
||||||
app:cornerRadius="16dp"
|
|
||||||
app:iconPadding="0dp"
|
|
||||||
android:insetTop="0dp"
|
|
||||||
android:insetBottom="0dp"
|
|
||||||
android:insetLeft="0dp"
|
|
||||||
android:insetRight="0dp"
|
|
||||||
android:layout_marginBottom="44dp"
|
|
||||||
android:tooltipText="@string/button_generate_text"
|
|
||||||
android:contentDescription="@string/button_generate_description"
|
|
||||||
app:icon="@drawable/pw_generate"
|
|
||||||
app:iconSize="0dp"
|
|
||||||
app:backgroundColor="@color/design_default_color_primary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.498"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
app:layout_constraintGuide_begin="20dp" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageViewPwLength"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/passwordLengthLabel"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/passwordLengthLabel"
|
|
||||||
app:layout_constraintVertical_bias="0.0"
|
|
||||||
app:srcCompat="@drawable/pw_straighten"
|
|
||||||
android:contentDescription="@string/image_length_desc" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageViewWithoutSpaces"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
android:layout_marginBottom="9dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/switchWithoutSpaces"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/switchWithoutSpaces"
|
|
||||||
app:layout_constraintVertical_bias="0.8"
|
|
||||||
app:srcCompat="@drawable/pw_letter_spacing"
|
|
||||||
android:contentDescription="@string/image_wospaces" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageViewAddSpecialChars"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/switchSpecialChars"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/switchSpecialChars"
|
|
||||||
app:layout_constraintVertical_bias="0.625"
|
|
||||||
app:srcCompat="@drawable/pw_special_character"
|
|
||||||
android:contentDescription="@string/image_specialchars" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline3"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_begin="16dp" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline4"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_begin="65dp" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/guideline5"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_percent="0.92" />
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@ -1,18 +1,12 @@
|
|||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<!-- <style name="Theme.PasswordZebra" parent="Theme.AppCompat.DayNight.DarkActionBar"> -->
|
<style name="Theme.PasswordZebra" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
<style name="Theme.PasswordZebra" parent="Theme.Material3.DayNight">
|
|
||||||
|
|
||||||
<!-- <style name="Theme.PasswordZebra" parent="Theme.Material3.DayNight.NoActionBar"> -->
|
|
||||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
<!-- status bar font color -->
|
<!-- status bar font color -->
|
||||||
<item name="android:windowLightStatusBar">false</item>
|
<item name="android:windowLightStatusBar">false</item>
|
||||||
<!-- true = status bar semi-transparent -->
|
<!-- true = status bar semi-transparent -->
|
||||||
<item name="android:windowTranslucentStatus">false</item>
|
<item name="android:windowTranslucentStatus">false</item>
|
||||||
|
|
||||||
<!-- action bar -->
|
|
||||||
<!-- defined in themes_overlays - item name="actionBarStyle" -->
|
|
||||||
|
|
||||||
<!-- navigation bar = bottom bar with navigation buttons -->
|
<!-- navigation bar = bottom bar with navigation buttons -->
|
||||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
<item name="android:windowLightNavigationBar">false</item>
|
<item name="android:windowLightNavigationBar">false</item>
|
||||||
@ -44,9 +38,4 @@
|
|||||||
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
|
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
|
||||||
<item name="colorPrimaryInverse">@color/md_theme_dark_inversePrimary</item>
|
<item name="colorPrimaryInverse">@color/md_theme_dark_inversePrimary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="MyActionBar" parent="@style/Widget.AppCompat.ActionBar">
|
|
||||||
<item name="background">@android:color/transparent</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<style name="Theme.PasswordZebra" parent="Theme.Material3.Light">
|
<style name="Theme.PasswordZebra" parent="Theme.Material3.Light.NoActionBar">
|
||||||
<!-- <style name="Theme.PasswordZebra" parent="Theme.Material3.Light.NoActionBar"> -->
|
|
||||||
|
|
||||||
<!-- statusbar background color -->
|
<!-- statusbar background color -->
|
||||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
@ -17,9 +15,4 @@
|
|||||||
<item name="android:windowLightNavigationBar">true</item>
|
<item name="android:windowLightNavigationBar">true</item>
|
||||||
<item name="android:windowTranslucentNavigation">false</item>
|
<item name="android:windowTranslucentNavigation">false</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="MyActionBar" parent="@style/Widget.AppCompat.ActionBar">
|
|
||||||
<item name="background">@android:color/transparent</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@ -1,6 +1,3 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources>
|
||||||
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight">
|
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight" />
|
||||||
<item name="actionBarStyle">@style/MyActionBar</item>
|
|
||||||
<!-- <item name="actionBarStyle">@style/Widget.AppCompat.ActionBar</item> -->
|
|
||||||
</style>
|
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
x
Reference in New Issue
Block a user