発車予定を表示するホーム画面を:feature:depart:homeモジュールに作成します。
uiモジュールの作成と同様に、トップディレクトリで:feature:depart:homeを作成し、javaディレクトリ名の変更、および、サンプルテストクラスの削除を行います。
発車予定画面は画面の表示データがありますのでViewModelを使用します。
Hiltと連携してViewModelを使用するためhilt-navigation-composeを導入します。
※navigation-composeは必要ありません。
バージョンカタログファイルにhilt-navigation-composeの定義を追記します。
[versions]
:
hilt-navigation-compose = "1.3.0" # https://mvnrepository.com/artifact/androidx.hilt/hilt-navigation-compose
:
lifecycleRuntimeKtx = "2.9.4"
lifecycle = "2.9.4"
:
[libraries]
:
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hilt-navigation-compose" }
:
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
:
追記後、『Sync Now』で内容をプロジェクトに反映させます。
:core:uiモジュールで作成したLibraryConfigurePlugin.ktを使用してもいいのですが、画面が複数ありますので、画面用のビルドプラグインを作成することにします。
/build-logic/src/main/kotlin内に画面ライブラリモジュールのbuild.gradle.ktsで使用するビルドプラグインを作成します。
ファイル名をFeatureConfigurePlugin.ktにしています。
package jp.co.progress_llc.buildlogic
import com.android.build.api.dsl.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
class FeatureConfigurePlugin: Plugin<Project> {
override fun apply(project: Project) = with(project) {
with(pluginManager) {
apply("com.android.library")
apply("org.jetbrains.kotlin.android")
apply("com.google.devtools.ksp")
apply("com.google.dagger.hilt.android")
apply("org.jetbrains.kotlin.plugin.compose")
}
extensions.configure<LibraryExtension> {
configureCommonExtension(this)
defaultConfig.consumerProguardFiles("consumer-rules.pro")
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
buildFeatures.compose = true
}
dependencies {
add("implementation", project.libs().findLibrary("androidx-core-ktx").get())
add("implementation", project.libs().findLibrary("androidx-appcompat").get())
add("implementation", project.libs().findLibrary("material").get())
add("implementation", project.libs().findLibrary("hilt-android").get())
add("implementation", project.libs().findLibrary("hilt-navigation-compose").get())
add("implementation", project.libs().findLibrary("androidx-lifecycle-runtime-ktx").get())
add("implementation", project.libs().findLibrary("androidx-lifecycle-viewmodel-compose").get())
add("implementation", platform(project.libs().findLibrary("compose-bom").get()))
add("implementation", project.libs().findLibrary("compose-ui").get())
add("implementation", project.libs().findLibrary("compose-material").get())
add("implementation", project.libs().findLibrary("androidx-ui-tooling-preview").get())
add("ksp", project.libs().findLibrary("hilt-compiler").get())
add("debugImplementation", platform(project.libs().findLibrary("compose-bom").get()))
add("debugImplementation", project.libs().findLibrary("androidx-ui-tooling").get())
}
}
}
作成したビルドプラグインをモジュールのbuild.gradle.ktsで使用できるようにbuild-logic直下のbuild.gradle.ktsに追記します。
:
gradlePlugin {
:
plugins {
register("FeatureConfigurePlugin") {
id = "build.logic.feature.configure"
implementationClass = "jp.co.progress_llc.buildlogic.FeatureConfigurePlugin"
}
}
}
dependencies {
:
追記後、『Sync Now』で内容をプロジェクトに反映させます。
:feature:depart:homeモジュールの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.home"
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)
}
適用後、『Sync Now』で内容をプロジェクトに反映させます。
UI層としてpresentationディレクトリを作成します。
発車予定画面として、暫定的にViewModelのないDepartHomeScreen.ktを作成します。
package jp.co.progress_llc.portal.feature.depart.home.presentation
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DepartHomeScreen(
) {
var expanded by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = "発車予定",
style = MaterialTheme.typography.headlineMedium
)
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
OutlinedTextField(
value = "",
onValueChange = {},
readOnly = true,
label = { Text("経路を選択") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
modifier = Modifier
.fillMaxWidth()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
// 新規経路オプション
DropdownMenuItem(
text = {
Text(
text = "編集/新規経路...",
color = MaterialTheme.colorScheme.primary
)
},
onClick = {
expanded = false
}
)
}
}
}
}
@Preview(showBackground = true)
@Composable
fun DepartHomeScreenPreview() {
DepartHomeScreen()
}