feat: refs #6659 jetPackCompose

This commit is contained in:
Sergio De la torre 2025-02-20 09:44:07 +01:00
parent 0c8df1c7a1
commit df8dc7cc77
7 changed files with 329 additions and 10 deletions

View File

@ -0,0 +1,220 @@
package es.verdnatura.presentation.composable
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
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 es.verdnatura.R
@Composable
fun CustomToolbar(
title: String,
subtitle: String? = null,
showBackButton: Boolean = true,
showSwitch: Boolean = false,
iconList: List<Int> = emptyList(),
onBackClick: () -> Unit = {},
onSwitchChange: (Boolean) -> Unit = {}
) {
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.Black)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
verticalAlignment = CenterVertically,
) {
if (showBackButton) {
IconButton(
onClick = { onBackClick() },
modifier = Modifier.padding(start = 0.dp),
) {
Icon(
painter = painterResource(id = R.drawable.ic_chevron_left),
contentDescription = "Back",
tint = Color.White
)
}
}
Text(
text = title,
color = Color.White,
fontSize = dimensionResource(id = R.dimen.title).value.sp,
fontWeight = FontWeight.Bold,
)
if (!subtitle.isNullOrEmpty()) {
Text(
modifier = Modifier.weight(1f),
text = subtitle,
color = Color.White.copy(alpha = 0.7f),
fontSize = dimensionResource(id = R.dimen.subtitle).value.sp
)
}
}
if (iconList.isNotEmpty()) {
LazyRow {
items(iconList) { iconRes ->
IconButton(onClick = { /* Acción del icono */ }) {
Icon(
painter = painterResource(id = iconRes),
contentDescription = "Icon",
tint = Color.White
)
}
}
}
}
if (showSwitch) {
var switchState by remember { mutableStateOf(false) }
Switch(
checked = switchState,
onCheckedChange = {
switchState = it
onSwitchChange(it)
}
)
}
}
HorizontalDivider(
thickness = 1.dp,
color = colorResource(id = R.color.verdnatura_brown_grey)
)
}
@Composable
fun ScanLineTextSearch(
value: String,
onValueChange: (String) -> Unit,
onImeAction: () -> Unit,
modifier: Modifier = Modifier.wrapContentSize(),
) {
val keyboardController = LocalSoftwareKeyboardController.current
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
TextField(
value = value,
onValueChange = onValueChange,
textStyle = TextStyle(
color = Color.White,
textAlign = TextAlign.Center
),
placeholder = {
Text(
text = stringResource(id = R.string.Escaneaetiqueta),
textAlign = TextAlign.Center,
color = Color.White,
modifier = Modifier.fillMaxWidth()
)
},
singleLine = true,
keyboardActions = KeyboardActions(
onDone = {
onImeAction()
}
),
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Done
),
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.DarkGray, // Fondo cuando está enfocado
unfocusedContainerColor = Color.DarkGray, // Fondo cuando NO está enfocado
cursorColor = Color.White, // Color del cursor
focusedTextColor = Color.White, // Color del texto cuando está enfocado
unfocusedTextColor = Color.White, // Color del texto cuando NO está enfocado
focusedPlaceholderColor = Color.Black, // Color del placeholder cuando está enfocado
unfocusedPlaceholderColor = Color.Black // Color del placeholder cuando NO está enfocado
),
modifier = modifier
.fillMaxWidth(fraction = 0.67f)
.border(2.dp, Color.White, RoundedCornerShape(8.dp))
.height(54.dp)
.padding(bottom = 4.dp)
.onFocusEvent {
if (it.isFocused) {
keyboardController?.hide()
}
}
)
}
}
@Preview
@Composable
fun PreviewToolbar() {
CustomToolbar(
title = "Mi Toolbar",
subtitle = "10/20",
showBackButton = true,
showSwitch = true,
iconList = listOf(R.drawable.ic_launcher_foreground, R.drawable.ic_launcher_foreground),
onBackClick = { /* Acción de volver atrás */ },
onSwitchChange = { /* Acción del switch */ }
)
}
@Preview
@Composable
fun PreviewScanLineTextSearch() {
ScanLineTextSearch(
value = "Escanea etiqueta",
onValueChange = {},
onImeAction = {})
}

View File

@ -0,0 +1,17 @@
package es.verdnatura.presentation.composable
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import es.verdnatura.R
class ImageViewActivityComposable : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val imageUrl = intent.getStringExtra(getString(R.string.url)) ?: ""
val title = intent.getStringExtra(getString(R.string.title)) ?: ""
ImageViewScreen(imageUrl = imageUrl, titleToolBar = title, onBackClick = { finish() })
}
}
}

View File

@ -0,0 +1,59 @@
package es.verdnatura.presentation.composable
import android.widget.ImageView
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.bumptech.glide.Glide
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ImageViewScreen(imageUrl: String, titleToolBar:String ="",onBackClick: () -> Unit ) {
CustomToolbar(
title = titleToolBar,
subtitle = "",
showBackButton = true,
showSwitch = false,
iconList = listOf(),
onBackClick = onBackClick ,
onSwitchChange = { }
)
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
) {
Spacer(modifier = Modifier.height(16.dp))
GlideImage(imageUrl = imageUrl)
}
}
@Composable
fun GlideImage(imageUrl: String) {
androidx.compose.ui.viewinterop.AndroidView(
factory = { context ->
ImageView(context).apply {
Glide.with(context)
.load(imageUrl)
.into(this)
}
},
modifier = Modifier.fillMaxSize()
)
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ImageViewScreen(imageUrl = "https://example.com/image.jpg", "titleToolbar") {}
}

View File

@ -6,26 +6,21 @@ import es.verdnatura.domain.toast
import es.verdnatura.presentation.base.BaseActivity import es.verdnatura.presentation.base.BaseActivity
import es.verdnatura.presentation.common.loadUrl import es.verdnatura.presentation.common.loadUrl
class ImageViewActivity : BaseActivity<ActivityImageviewBinding>(){ class ImageViewActivity : BaseActivity<ActivityImageviewBinding>() {
override fun getLayoutId(): Int = R.layout.activity_imageview override fun getLayoutId(): Int = R.layout.activity_imageview
override fun init() { override fun init() {
binding.mainToolbar.toolbarTitle.text = intent.getStringExtra(getString(R.string.title)) binding.mainToolbar.toolbarTitle.text = intent.getStringExtra(getString(R.string.title))
try { try {
binding.imgView.loadUrl(intent.getStringExtra(getString(R.string.url))!!) binding.imgView.loadUrl(intent.getStringExtra(getString(R.string.url))!!)
}catch(ex:Exception){ } catch (ex: Exception) {
getString(R.string.errorImage).toast(this) getString(R.string.errorImage).toast(this)
finish() finish()
} }
binding.mainToolbar.backButton.setOnClickListener { binding.mainToolbar.backButton.setOnClickListener {
finish() finish()
} }
} }
} }

View File

@ -27,6 +27,7 @@ import es.verdnatura.presentation.common.ToolBarAdapterTooltip
import es.verdnatura.presentation.common.hideKeyboard import es.verdnatura.presentation.common.hideKeyboard
import es.verdnatura.presentation.common.itemScanValue import es.verdnatura.presentation.common.itemScanValue
import es.verdnatura.presentation.common.loadUrl import es.verdnatura.presentation.common.loadUrl
import es.verdnatura.presentation.composable.ImageViewActivityComposable
import es.verdnatura.presentation.view.component.CustomDialogDynamicButtons import es.verdnatura.presentation.view.component.CustomDialogDynamicButtons
import es.verdnatura.presentation.view.component.CustomDialogInput import es.verdnatura.presentation.view.component.CustomDialogInput
import es.verdnatura.presentation.view.component.CustomDialogList import es.verdnatura.presentation.view.component.CustomDialogList
@ -272,7 +273,9 @@ class ItemCardFragment(
} }
binding.itemcardImage.setOnClickListener { binding.itemcardImage.setOnClickListener {
val i = Intent(activity, ImageViewActivity::class.java) //JETPACKCOMPOSE
// val i = Intent(activity, ImageViewActivity::class.java)
val i = Intent(activity, ImageViewActivityComposable::class.java)
i.putExtra(getString(R.string.url), urlLarge) i.putExtra(getString(R.string.url), urlLarge)
i.putExtra(getString(R.string.title), titleImage) i.putExtra(getString(R.string.title), titleImage)
startActivity(i) startActivity(i)

View File

@ -40,6 +40,10 @@
<!--List separation--> <!--List separation-->
<dimen name="item_list_separation">4dp</dimen> <dimen name="item_list_separation">4dp</dimen>
<!--text toolbar-->
<dimen name="title">18sp</dimen>
<dimen name="subtitle">16sp</dimen>
<!--Text sizes--> <!--Text sizes-->
<dimen name="h1">96sp</dimen> <dimen name="h1">96sp</dimen>
<dimen name="h2">60sp</dimen> <dimen name="h2">60sp</dimen>

View File

@ -1,4 +1,5 @@
[versions] [versions]
activityCompose = "1.9.2"
androidImagePicker = "3.0.0-beta5" androidImagePicker = "3.0.0-beta5"
appcompat = "1.7.0" appcompat = "1.7.0"
constraintlayout = "2.2.0" constraintlayout = "2.2.0"
@ -12,10 +13,13 @@ fragmentKtx = "1.8.5"
glide = "4.16.0" glide = "4.16.0"
ink = "1.0.0" ink = "1.0.0"
koin = "2.1.6" koin = "2.1.6"
koinAndroidxCompose = "3.5.3"
kotlinStdlibJdk7 = "2.0.0" kotlinStdlibJdk7 = "2.0.0"
legacySupportV4 = "1.0.0" legacySupportV4 = "1.0.0"
lifecycleExtensions = "2.2.0" lifecycleExtensions = "2.2.0"
lifecycleViewmodelCompose = "2.8.5"
lifecycleViewmodelKtx = "2.8.7" lifecycleViewmodelKtx = "2.8.7"
lottieCompose = "6.3.0"
lottieVersion = "3.4.0" lottieVersion = "3.4.0"
material = "1.12.0" material = "1.12.0"
navigationFragmentKtx = "2.8.6" navigationFragmentKtx = "2.8.6"
@ -32,11 +36,14 @@ androidGradlePlugin = "8.7.3"
kotlin = "2.0.20" kotlin = "2.0.20"
googleServices = "4.4.2" googleServices = "4.4.2"
firebaseCrashlytics = "3.0.3" firebaseCrashlytics = "3.0.3"
junit = "4.12"
[libraries] [libraries]
#pickerImage #pickerImage
android-image-picker = { module = "com.github.esafirm:android-image-picker", version.ref = "androidImagePicker" } android-image-picker = { module = "com.github.esafirm:android-image-picker", version.ref = "androidImagePicker" }
#android #android
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }
androidx-adaptive = { module = "androidx.compose.material3.adaptive:adaptive" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" } androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" } androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
@ -48,7 +55,12 @@ androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref
androidx-legacy-support-v4 = { module = "androidx.legacy:legacy-support-v4", version.ref = "legacySupportV4" } androidx-legacy-support-v4 = { module = "androidx.legacy:legacy-support-v4", version.ref = "legacySupportV4" }
androidx-lifecycle-extensions = { module = "androidx.lifecycle:lifecycle-extensions", version.ref = "lifecycleExtensions" } androidx-lifecycle-extensions = { module = "androidx.lifecycle:lifecycle-extensions", version.ref = "lifecycleExtensions" }
androidx-lifecycle-livedata-ktx = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "lifecycleViewmodelKtx" } androidx-lifecycle-livedata-ktx = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "lifecycleViewmodelKtx" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycleViewmodelCompose" }
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" } androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
androidx-material = { module = "androidx.compose.material:material" }
androidx-material-icons-core = { module = "androidx.compose.material:material-icons-core" }
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" }
androidx-material3 = { module = "androidx.compose.material3:material3" }
androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigationUiKtx" } androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigationUiKtx" }
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" } androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
#room #room
@ -56,10 +68,18 @@ androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref =
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "roomCompiler" } androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "roomCompiler" }
#ui #ui
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomCompiler" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomCompiler" }
androidx-runtime-livedata = { module = "androidx.compose.runtime:runtime-livedata" }
androidx-ui = { module = "androidx.compose.ui:ui" }
androidx-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4" }
androidx-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" }
androidx-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
androidx-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" } converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" }
converter-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" } converter-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" }
#qr #qr
core = { module = "com.google.zxing:core", version.ref = "core" } core = { module = "com.google.zxing:core", version.ref = "core" }
koin-androidx-compose = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koinAndroidxCompose" }
lottie-compose = { module = "com.airbnb.android:lottie-compose", version.ref = "lottieCompose" }
zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "zxingAndroidEmbedded" } zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "zxingAndroidEmbedded" }
#analytics #analytics
firebase-analytics = { module = "com.google.firebase:firebase-analytics", version.ref = "firebaseAnalyticsKtx" } firebase-analytics = { module = "com.google.firebase:firebase-analytics", version.ref = "firebaseAnalyticsKtx" }
@ -90,8 +110,9 @@ androidGradlePlugin = { module = "com.android.tools.build:gradle", version.ref =
kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
googleServices = { module = "com.google.gms:google-services", version.ref = "googleServices" } googleServices = { module = "com.google.gms:google-services", version.ref = "googleServices" }
firebaseCrashlyticsGradle = { module = "com.google.firebase:firebase-crashlytics-gradle", version.ref = "firebaseCrashlytics" } firebaseCrashlyticsGradle = { module = "com.google.firebase:firebase-crashlytics-gradle", version.ref = "firebaseCrashlytics" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
[plugins] [plugins]
google-devtools-ksp = { id = "com.google.devtools.ksp", version.ref = "googleDevtoolsKsp" } google-devtools-ksp = { id = "com.google.devtools.ksp", version.ref = "googleDevtoolsKsp" }
#jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
#compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }