経路一覧を編集する画面を:feature:depart:routeモジュールに作成します。
共通UIモジュールの作成と同様に、トップディレクトリで:feature:depart:routeを作成し、javaディレクトリ名の変更、および、サンプルテストクラスの削除を行います。
:feature:depart:routeモジュールのbuild.gradle.ktsにビルドプラグインを適用します。
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
id("build.logic.feature.configure")
}
android {
namespace = "jp.co.progress_llc.portal.feature.depart.route"
compileSdk {
version = release(36)
}
defaultConfig {
minSdk = 28
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation(project(":core:ui"))
}
適用後、『Sync Now』で内容をプロジェクトに反映させます。
:feature:depart:routeモジュールにpresentationディレクトリ(パッケージ)を追加し、直下にDepartRouteScreen.ktを作成します。
※暫定的にViewModelのない画面として作成します。
package jp.co.progress_llc.portal.feature.depart.route.presentation
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import jp.co.progress_llc.portal.core.ui.components.AppTitleBox
import jp.co.progress_llc.portal.core.ui.theme.AppTheme
import jp.co.progress_llc.portal.core.ui.components.CustomOutlinedTextField
private object FieldName {
const val ROUTE = "経路名"
const val DEPARTURE = "発駅"
const val VIA = "経由駅"
const val ARRIVAL = "着駅"
}
@Composable
fun DepartRouteScreen() {
var routeName by remember { mutableStateOf(FieldName.ROUTE) }
var departureStation by remember { mutableStateOf(FieldName.DEPARTURE) }
var viaStation by remember { mutableStateOf(FieldName.VIA) }
var arrivalStation by remember { mutableStateOf(FieldName.ARRIVAL) }
Scaffold(
topBar = { AppTitleBox() }
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.padding(8.dp),
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
Text(
text = "経路一覧編集",
style = MaterialTheme.typography.titleLarge,
)
// 新規登録行
Card(
modifier = Modifier
.fillMaxWidth()
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.outline,
shape = MaterialTheme.shapes.small
)
.padding(horizontal = 8.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.background
)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 10.dp)
) {
CustomOutlinedTextField(
value = routeName,
onValueChange = { value: String -> routeName = value },
label = {
Text(
text = FieldName.ROUTE,
style = MaterialTheme.typography.bodySmall
)
},
modifier = Modifier.fillMaxWidth(),
textStyle = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.primary
),
contentPadding = PaddingValues(start = 8.dp, end = 8.dp, top = 2.dp),
shape = RoundedCornerShape(6.dp),
singleLine = true,
height = 32.dp
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp, bottom = 4.dp)
) {
CustomOutlinedTextField(
value = departureStation,
onValueChange = { value: String -> departureStation = value },
label = {
Text(
text = FieldName.DEPARTURE,
style = MaterialTheme.typography.bodySmall
)
},
modifier = Modifier.weight(1f),
textStyle = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.primary,
textDecoration = TextDecoration.Underline
),
readOnly = true,
contentPadding = PaddingValues(start = 8.dp, end = 8.dp, top = 2.dp),
shape = RoundedCornerShape(6.dp),
singleLine = true,
height = 32.dp
)
Spacer(modifier = Modifier.width(6.dp))
CustomOutlinedTextField(
value = viaStation,
onValueChange = { value: String -> viaStation = value },
label = {
Text(
text = FieldName.VIA,
style = MaterialTheme.typography.bodySmall
)
},
modifier = Modifier.weight(1f),
textStyle = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.primary,
textDecoration = TextDecoration.Underline
),
readOnly = true,
contentPadding = PaddingValues(start = 8.dp, end = 8.dp, top = 2.dp),
shape = RoundedCornerShape(6.dp),
singleLine = true,
height = 32.dp
)
Spacer(modifier = Modifier.width(6.dp))
CustomOutlinedTextField(
value = arrivalStation,
onValueChange = { value: String -> arrivalStation = value },
label = {
Text(
text = FieldName.ARRIVAL,
style = MaterialTheme.typography.bodySmall
)
},
modifier = Modifier.weight(1f),
textStyle = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.primary,
textDecoration = TextDecoration.Underline
),
readOnly = true,
contentPadding = PaddingValues(start = 8.dp, end = 8.dp, top = 2.dp),
shape = RoundedCornerShape(6.dp),
singleLine = true,
height = 32.dp
)
}
// ボタン行
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 4.dp, bottom = 10.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)
) {
Button(
onClick = { },
modifier = Modifier
.height(28.dp)
.width(80.dp),
contentPadding = PaddingValues(horizontal = 8.dp)
) {
Text("登録", style = MaterialTheme.typography.bodySmall)
}
OutlinedButton(
onClick = {
routeName = FieldName.ROUTE
departureStation = FieldName.DEPARTURE
viaStation = FieldName.VIA
arrivalStation = FieldName.ARRIVAL
},
modifier = Modifier
.height(28.dp)
.width(80.dp),
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 4.dp),
colors = ButtonDefaults.outlinedButtonColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer,
contentColor = MaterialTheme.colorScheme.onSecondaryContainer
)
) {
Text("クリア", style = MaterialTheme.typography.bodySmall)
}
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun DepartRouteScreenPreview() {
AppTheme {
DepartRouteScreen()
}
}