ETS PBB I 2024
ETS PBB - Redesign Aplikasi Traveloka
Pertanyaan:
Gambarkan dan Jelaskan siklus aktivitas dari aplikasi Android?
Penggunaan aplikasi Android yang sesuai di bidang apa saja? Jelaskan dan berikan contohnya.
Bukalah aplikasi Mobile yang berkaitan dengan sistem Tiket yang anda punya. Tuliskan dan jelaskan kegunaan fitur yang sering dipakai.
Redesign dan aplikasi sesuai dengan fitur yang dipakai.
Implementasi dalam bentuk aplikasi Android halaman masuk dan akses fitur yang sering dipakai.
Dokumentasikan dan Demokan dalam Video Youtube dari aplikasi yang telah dibangun.
Jawaban:
Berikut gambaran dari Activity Cycle dari aplikasi Android:
Penjelasan:
onCreate(): Dipanggil saat aktivitas pertama kali dibuat. Di sini dapat menginisialisasi komponen-komponen penting seperti layout UI, variabel, dsb.
onStart(): Dipanggil saat aktivitas akan menjadi terlihat oleh pengguna.
onResume(): Dipanggil saat aktivitas mulai berinteraksi dengan pengguna. Aktivitas berada di puncak Activity Cycle dan disinilah aktivitas berjalan penuh.
onPause(): Dipanggil saat aktivitas kehilangan fokus tetapi masih terlihat oleh pengguna. Biasanya digunakan untuk menyimpan perubahan sementara.
onStop(): Dipanggil saat aktivitas tidak lagi terlihat oleh pengguna. Aktivitas akan berada dalam keadaan berhenti.
onRestart(): Dipanggil saat aktivitas yang berhenti akan dimulai lagi.
onDestroy(): Dipanggil sebelum aktivitas dihancurkan. Biasanya digunakan untuk membersihkan resource.
Penggunaan aplikasi Android dapat digunakan diberbagai bidang (terutama dibidang yang menawarkan jasa dengan menggunakan Software/SaaS [Software as a service] dalam melaksanakan bisnisnya) karena aplikasi ini sangat versatile dan mudah digunakan (dan dikembangankan), berikut contoh bidang yang dapat menggunakan aplikasi Android:
E-commerce: Aplikasi seperti Tokopedia, Shopee, dan Lazada memungkinkan pengguna untuk belanja online, membandingkan harga, dan membaca ulasan produk.
Pendidikan: Aplikasi seperti Ruangguru dan Zenius menyediakan materi pembelajaran, latihan soal, dan video tutorial untuk siswa.
Kesehatan: Aplikasi Halodoc dan Alodokter menyediakan konsultasi medis online, pemesanan obat, dan informasi kesehatan.
Transportasi: Aplikasi seperti Gojek dan Grab digunakan untuk memesan transportasi, pengantaran makanan, dan layanan lainnya.
Perjalanan dan Pemesanan Tiket: Aplikasi Traveloka dan Tiket.com digunakan untuk memesan tiket pesawat, kereta api, hotel, dan kegiatan wisata.
Aplikasi Mobile yang berkaitan dengan sistem Tiket yang sering saya pakai adalah Traveloka yang berguna untuk memesan Tiket Penerbangan dan Hotel, berikut fitur yang sering digunakan:
Booking (Pemesanan Tiket):
Fitur ini merupakan fitur utama dalam aplikasi Traveloka karena tujuan aplikasi ini adalah membantu kita mempermudah pemesanan tiket pesawat melalui aplikasi mobile tanpa perlu memesan lewat website penerbangan yang dimana lebih ribet dan tidak dapat membandingkan harga antara maskapai.
Transaction (History Pemesanan):
Fitur ini merupakan fitur penting yang saya sering gunakan karena fitur ini membantu pengguna untuk melihat dan mengelola pemesanan tiket yang telah kita beli (mau yang sedang berjalan atau sudah berlalu).
Berikut redesign dari fitur aplikasi yang sering digunakan:
- Berikut merupakan implementasi dari aplikasi Android Traveloka dengan membuat fitur
authentication dan pemesanan tiket, sebagai berikut:
Source Code:
OnboardingScreen.kt:
LoginScreen.kt:
package com.example.travelokabaru.ui.screen.authentication
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.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.travelokabaru.R
import com.example.travelokabaru.ui.components.BackgroundImage
import com.example.travelokabaru.ui.theme.TravelokabaruTheme
@Composable
fun OnboardingScreen(
navigateToRegistration: (() -> Unit),
navigateToLogin: (() -> Unit)
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surface)
) {
BackgroundImage(
image = painterResource(id = R.drawable.background),
alpha = 0.7f
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxSize()
.padding(32.dp)
) {
Header()
Spacer(modifier = Modifier.height(350.dp))
Action(
navigateToRegistration = navigateToRegistration,
navigateToLogin = navigateToLogin
)
}
}
}
@Composable
private fun Header() {
Image(
painter = painterResource(id = R.drawable.ic_traveloka),
contentDescription = null,
modifier = Modifier.width(500.dp)
)
}
@Composable
private fun Action(
navigateToRegistration: (() -> Unit),
navigateToLogin: (() -> Unit)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(
onClick = navigateToLogin,
modifier = Modifier.width(240.dp)
) {
Text(text = "Login")
}
Spacer(modifier = Modifier.height(7.dp))
Button(
onClick = navigateToLogin,
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
contentColor = MaterialTheme.colorScheme.onTertiaryContainer
),
modifier = Modifier.width(240.dp)
) {
Text(text = "Register")
}
}
}
@Preview(showBackground = true)
@Composable
private fun LightThemePreview() {
TravelokabaruTheme {
OnboardingScreen(navigateToRegistration = {}, navigateToLogin = {})
}
}
@Preview(showBackground = true)
@Composable
private fun DarkThemePreview() {
TravelokabaruTheme(
darkTheme = true
) {
OnboardingScreen(navigateToRegistration = {}, navigateToLogin = {})
}
}HomeScreen.kt:package com.example.travelokabaru.ui.screen.authentication
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Email
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
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 com.example.travelokabaru.R
import com.example.travelokabaru.ui.components.CustomOutlinedButtonWithIcon
import com.example.travelokabaru.ui.components.CustomOutlinedPasswordField
import com.example.travelokabaru.ui.components.CustomOutlinedTextField
import com.example.travelokabaru.ui.theme.TravelokabaruTheme
@Composable
fun LoginScreen(
navigateToHome: (() -> Unit)
) {
Box(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface)
.fillMaxSize()
.padding(32.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
Header()
Main(navigateToHome = navigateToHome)
}
Footer()
}
}
@Composable
private fun Header() {
Column {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Login Account",
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onSurface,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Please login with registered account",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.surfaceTint
)
}
}
@Composable
private fun Main(
navigateToHome: (() -> Unit)
) {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
Spacer(modifier = Modifier.height(4.dp))
CustomOutlinedTextField(
label = "Email or Phone Number",
placeholder = "Enter your email or phone number",
trailingIcon = Icons.Default.Email
)
CustomOutlinedPasswordField(
label = "Password",
placeholder = "Enter your password",
)
Text(
text = "Forget Password?",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.tertiary,
textAlign = TextAlign.End,
modifier = Modifier
.fillMaxWidth()
.clickable { }
)
}
Spacer(modifier = Modifier.height(4.dp))
Button(
onClick = navigateToHome,
modifier = Modifier.fillMaxWidth()
) {
Text(text = "Login")
}
Text(
text = "Or using another method",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Column(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
CustomOutlinedButtonWithIcon(
label = "Sign In with Google",
icon = painterResource(id = R.drawable.ic_google),
onClick = {}
)
CustomOutlinedButtonWithIcon(
label = "Sign In with Facebook",
icon = painterResource(id = R.drawable.ic_facebook),
onClick = {}
)
}
}
@Composable
private fun Footer() {
Row(
verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxSize()
) {
Image(
painter = painterResource(id = R.drawable.ic_traveloka),
contentDescription = null,
modifier = Modifier.height(90.dp)
)
}
}
@Preview(showBackground = true)
@Composable
private fun LightThemePreview() {
TravelokabaruTheme {
LoginScreen(navigateToHome = {})
}
}
@Preview(showBackground = true)
@Composable
private fun DarkThemePreview() {
TravelokabaruTheme(
darkTheme = true
) {
LoginScreen(navigateToHome = {})
}
}FindTicketScreen.kt:package com.example.travelokabaru.ui.screen.home
import android.app.Activity
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.SwapHoriz
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Divider
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
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.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.travelokabaru.R
import com.example.travelokabaru.data.HomeData
import com.example.travelokabaru.data.articleData
import com.example.travelokabaru.data.promoData
import com.example.travelokabaru.ui.components.HomeTopBar
import com.example.travelokabaru.ui.theme.TravelokabaruTheme
@Composable
fun HomeScreen(
navigateToFindTicket: (() -> Unit),
) {
Scaffold(
topBar = {
HomeTopBar()
},
) { innerPadding ->
val context = LocalContext.current
BackHandler {
(context as? Activity)?.finish()
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
// item {
// Header()
// }
item {
FindTiketCard(
navigateToFindTicket = navigateToFindTicket
)
}
item {
Section(title = "Popular Routes ✨", data = promoData)
}
item {
Section(title = "Hot Promos 🔥", data = articleData)
}
}
}
}
}
@Composable
private fun Section(
title: String,
data: List<HomeData>
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxWidth()
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = title,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Text(
text = "See All",
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.scrim,
fontWeight = FontWeight.Bold,
modifier = Modifier.clickable { }
)
}
LazyRow(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxWidth()
) {
items(data) { item ->
Column(
verticalArrangement = Arrangement.spacedBy(6.dp),
modifier = Modifier.width(150.dp)
) {
Image(
painter = item.image,
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier
.size(width = 150.dp, height = 150.dp)
.clip(RoundedCornerShape(16.dp))
)
Text(
text = item.title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.fillMaxWidth()
)
}
}
}
}
}
@Composable
private fun FindTiketCard(
navigateToFindTicket: (() -> Unit)
) {
ElevatedCard(
elevation = CardDefaults.cardElevation(
defaultElevation = 10.dp
),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.primary
),
modifier = Modifier
.fillMaxWidth()
) {
// var checked by remember {
// mutableStateOf(false)
// }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(16.dp)
) {
Spacer(modifier = Modifier.height(10.dp))
Row (verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
){
TextField(
value = "Jakarta, Indonesia",
onValueChange = {},
label = { Text("From") },
modifier = Modifier.fillMaxWidth()
)
}
Spacer(modifier = Modifier.height(6.dp))
Row (verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
){
TextField(
value = "New York, USA",
onValueChange = {},
label = { Text("To") },
modifier = Modifier.fillMaxWidth()
)
}
Spacer(modifier = Modifier.height(6.dp))
Row(verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
modifier = Modifier.fillMaxWidth()
) {
Checkbox(
checked = false,
onCheckedChange = {}
)
Text(text = "Round Trip")
}
// Spacer(modifier = Modifier.height(1.dp))
// Divider()
// Spacer(modifier = Modifier.height(2.dp))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.clickable { }
) {
Text(
text = "Depature Date",
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Bold,
modifier = Modifier.alpha(0.7f)
)
Text(
text = "Saturday, 18 Mei 2024",
style = MaterialTheme.typography.bodySmall,
)
}
Button(
onClick = navigateToFindTicket,
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
contentColor = MaterialTheme.colorScheme.scrim
),
) {
Text(text = "Find Ticket")
}
}
}
}
}
@Preview(showBackground = true)
@Composable
private fun LightThemePreview() {
TravelokabaruTheme {
HomeScreen(navigateToFindTicket = {})
}
}
@Preview(showBackground = true)
@Composable
private fun DarkThemePreview() {
TravelokabaruTheme(
darkTheme = true
) {
HomeScreen(navigateToFindTicket = {})
}
}OrderSuccessScreen.kt:package com.example.travelokabaru.ui.screen.ticket
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Divider
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.travelokabaru.data.Ticket
import com.example.travelokabaru.data.ticketList
import com.example.travelokabaru.ui.components.CustomCenterAlignedTopBar
import com.example.travelokabaru.ui.theme.TravelokabaruTheme
@Composable
fun FindTicketScreen(
navigateToOrderTicket: (() -> Unit),
navigateBack: (() -> Unit)
) {
Scaffold(
topBar = {
CustomCenterAlignedTopBar(title="Search Ticket", navigateBack = navigateBack,)
},
) { innerPadding ->
Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface)
.fillMaxSize()
.padding(innerPadding)
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
DateCard(date = "16", day = "Thr")
DateCard(date = "17", day = "Fri")
DateCard(date = "18", day = "San", now = true)
DateCard(date = "19", day = "Sun")
DateCard(date = "20", day = "Mon")
}
LazyColumn(
verticalArrangement = Arrangement.spacedBy(14.dp),
modifier = Modifier
.fillMaxWidth()
.padding(12.dp)
) {
items(ticketList) { ticket ->
TicketCard(
data = ticket,
navigateToOrderTicket = navigateToOrderTicket
)
}
}
}
}
}
@Composable
private fun TicketCard(
data: Ticket,
navigateToOrderTicket: (() -> Unit)
) {
ElevatedCard(
elevation = CardDefaults.cardElevation(
defaultElevation = 6.dp
),
modifier = Modifier
.fillMaxWidth()
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Column(
verticalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.size(width = 250.dp, height = 100.dp)
) {
Text(
text = data.argo,
style = MaterialTheme.typography.titleSmall,
modifier = Modifier.fillMaxWidth()
)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Column {
Text(
text = "JKT",
style = MaterialTheme.typography.labelMedium,
)
Text(
text = data.startLeaving,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.alpha(0.7f)
)
}
Divider(Modifier.width(150.dp))
Column(
horizontalAlignment = Alignment.End
) {
Text(
text = "NYC",
style = MaterialTheme.typography.labelMedium,
fontWeight = FontWeight.Bold,
)
Text(
text = data.arrive,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.alpha(0.7f)
)
}
}
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = data.argoClass,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier
.background(MaterialTheme.colorScheme.primary)
.padding(vertical = 4.dp, horizontal = 8.dp)
)
Text(
text = data.estimatedTime,
style = MaterialTheme.typography.bodySmall,
)
}
}
Column(
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.End,
modifier = Modifier.size(width = 250.dp, height = 100.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
horizontalAlignment = Alignment.End
) {
Text(
text = data.price,
style = MaterialTheme.typography.labelMedium,
fontWeight = FontWeight.Bold
)
Text(
text = "Sisa " + data.ticketRemaining.toString(),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error
)
}
FilledIconButton(
onClick = navigateToOrderTicket,
colors = IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
contentColor = MaterialTheme.colorScheme.onTertiaryContainer
),
modifier = Modifier.size(30.dp)
) {
Icon(
imageVector = Icons.Default.ArrowForward,
contentDescription = null,
)
}
}
}
}
}
@Composable
private fun DateCard(
date: String,
day: String,
now: Boolean = false
) {
ElevatedCard(
elevation = CardDefaults.cardElevation(
defaultElevation = 8.dp
),
colors = CardDefaults.cardColors(
containerColor = if (now) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface
),
modifier = Modifier.clickable { }
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(20.dp)
) {
Text(
text = date,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Text(
text = day,
style = MaterialTheme.typography.bodySmall
)
}
}
}
@Preview(showBackground = true)
@Composable
private fun LightThemePreview() {
TravelokabaruTheme {
FindTicketScreen(navigateToOrderTicket = {}, navigateBack = {})
}
}
@Preview(showBackground = true)
@Composable
private fun DarkThemePreview() {
TravelokabaruTheme(
darkTheme = true
) {
FindTicketScreen(navigateToOrderTicket = {}, navigateBack = {})
}
}Screenshoots:package com.example.travelokabaru.ui.screen.ticket
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
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 com.example.travelokabaru.R
import com.example.travelokabaru.ui.components.BackgroundImage
import com.example.travelokabaru.ui.theme.TravelokabaruTheme
@Composable
fun OrderSuccessScreen(
navigateToHome: (() -> Unit)
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surface)
) {
BackgroundImage(
image = painterResource(id = R.drawable.background_2),
)
Column(
verticalArrangement = Arrangement.Bottom,
modifier = Modifier.fillMaxSize()
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(12.dp),
modifier = Modifier
.clip(RoundedCornerShape(topStart = 32.dp, topEnd = 32.dp))
.background(MaterialTheme.colorScheme.surface)
.fillMaxWidth()
.padding(32.dp)
) {
Icon(
imageVector = Icons.Default.CheckCircle,
tint = MaterialTheme.colorScheme.primary,
contentDescription = null,
modifier = Modifier.size(100.dp)
)
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = "Payment Successful",
style = MaterialTheme.typography.headlineLarge,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onSurface
)
}
Button(
onClick = navigateToHome,
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
contentColor = MaterialTheme.colorScheme.onTertiaryContainer
),
) {
Text(text = "Back to Home")
}
}
}
}
}
@Preview(showBackground = true)
@Composable
private fun LightThemePreview() {
TravelokabaruTheme {
OrderSuccessScreen(navigateToHome = {})
}
}
@Preview(showBackground = true)
@Composable
private fun DarkThemePreview() {
TravelokabaruTheme(
darkTheme = true
) {
OrderSuccessScreen(navigateToHome = {})
}
} - Dokumentasi dan Demo: Youtube
Comments
Post a Comment