Preview Lottie by scanning QR Code
This commit is contained in:
@@ -129,5 +129,5 @@ dependencies {
|
|||||||
testImplementation(Libs.mockk_core)
|
testImplementation(Libs.mockk_core)
|
||||||
androidTestImplementation(Libs.mockk_android)
|
androidTestImplementation(Libs.mockk_android)
|
||||||
|
|
||||||
debugImplementation(Libs.leakcanary_android)
|
debugImplementation(Libs.code_scanner)
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
package="com.ericampire.android.androidstudycase">
|
package="com.ericampire.android.androidstudycase">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package com.ericampire.android.androidstudycase.presentation.custom
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import com.airbnb.lottie.compose.*
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LottiePreviewDialog(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
url: String,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
onError: (String?) -> Unit
|
||||||
|
) {
|
||||||
|
|
||||||
|
val composition by rememberLottieComposition(
|
||||||
|
spec = LottieCompositionSpec.Url(url),
|
||||||
|
onRetry = { _, previousException ->
|
||||||
|
onError(previousException.localizedMessage)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
val progress by animateLottieCompositionAsState(
|
||||||
|
composition = composition,
|
||||||
|
iterations = LottieConstants.IterateForever,
|
||||||
|
)
|
||||||
|
|
||||||
|
Dialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
content = {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.size(400.dp)
|
||||||
|
.background(color = Color.White, shape = MaterialTheme.shapes.medium),
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
content = {
|
||||||
|
LottieAnimation(
|
||||||
|
modifier = Modifier
|
||||||
|
.matchParentSize()
|
||||||
|
.padding(10.dp)
|
||||||
|
.clip(MaterialTheme.shapes.medium),
|
||||||
|
composition = composition,
|
||||||
|
progress = progress,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
+45
-1
@@ -1,13 +1,57 @@
|
|||||||
package com.ericampire.android.androidstudycase.presentation.screen.preview.ui
|
package com.ericampire.android.androidstudycase.presentation.screen.preview.ui
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.material.Scaffold
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import com.budiyev.android.codescanner.CodeScanner
|
||||||
|
import com.budiyev.android.codescanner.CodeScannerView
|
||||||
|
import com.ericampire.android.androidstudycase.R
|
||||||
|
import com.ericampire.android.androidstudycase.presentation.custom.LottiePreviewDialog
|
||||||
import com.ericampire.android.androidstudycase.presentation.screen.preview.business.PreviewViewModel
|
import com.ericampire.android.androidstudycase.presentation.screen.preview.business.PreviewViewModel
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PreviewScreen(
|
fun PreviewScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
viewModel: PreviewViewModel
|
viewModel: PreviewViewModel
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
var codeScanner: CodeScanner? = null
|
||||||
|
var lottieFileUrl by remember { mutableStateOf("") }
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
content = {
|
||||||
|
if (lottieFileUrl.isNotEmpty()) {
|
||||||
|
LottiePreviewDialog(
|
||||||
|
url = lottieFileUrl,
|
||||||
|
onError = {
|
||||||
|
Toast.makeText(context, it, Toast.LENGTH_LONG).show()
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
lottieFileUrl = ""
|
||||||
|
codeScanner?.startPreview()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
AndroidView(
|
||||||
|
factory = { context ->
|
||||||
|
val view = LayoutInflater.from(context).inflate(R.layout.code_scanner, null, false)
|
||||||
|
val scannerView = view.findViewById<CodeScannerView>(R.id.scanner_view)
|
||||||
|
codeScanner = CodeScanner(context, scannerView).apply {
|
||||||
|
startPreview()
|
||||||
|
}
|
||||||
|
codeScanner?.setDecodeCallback {
|
||||||
|
lottieFileUrl = it.text
|
||||||
|
}
|
||||||
|
view
|
||||||
|
},
|
||||||
|
update = { }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.budiyev.android.codescanner.CodeScannerView
|
||||||
|
android:id="@+id/scanner_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:autoFocusButtonColor="@android:color/white"
|
||||||
|
app:autoFocusButtonVisible="true"
|
||||||
|
app:flashButtonColor="@android:color/white"
|
||||||
|
app:flashButtonVisible="true"
|
||||||
|
app:frameColor="@android:color/white"
|
||||||
|
app:frameCornersSize="50dp"
|
||||||
|
app:frameCornersRadius="0dp"
|
||||||
|
app:frameAspectRatioWidth="1"
|
||||||
|
app:frameAspectRatioHeight="1"
|
||||||
|
app:frameSize="0.75"
|
||||||
|
app:frameThickness="2dp"
|
||||||
|
app:maskColor="#77000000" />
|
||||||
|
</FrameLayout>
|
||||||
@@ -147,4 +147,5 @@ object Libs {
|
|||||||
const val orbit_mvi_test = "org.orbit-mvi:orbit-test:4.2.0"
|
const val orbit_mvi_test = "org.orbit-mvi:orbit-test:4.2.0"
|
||||||
|
|
||||||
const val joda_time = "net.danlew:android.joda:2.10.9"
|
const val joda_time = "net.danlew:android.joda:2.10.9"
|
||||||
|
const val code_scanner = "com.budiyev.android:code-scanner:2.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user