diff --git a/README.md b/README.md
index b23505504..a7dd3e3eb 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,24 @@
-# android-movie-ticket
\ No newline at end of file
+# android-movie-ticket
+
+## 액티비티
+- MovieListActivity
+- TicketingActivity
+- MovieTicketActivity
+
+## 어댑터
+- MoviesAdapter
+
+## 데이터
+- Movie
+ - 이미지, 제목, 상영일(PlayingTimes), 러닝타임, 소개
+- TicketingInfo
+ - 영화 이름, 상영일, 몇명, 가격, 무슨 결제
+- Price
+ - 음수 체크
+ - 티켓 한 장의 가격은 13000원
+ - 영화 가격에 할인을 적용한다.
+ - Discount 구현 클래스를 리스트로 받는다.
+- PlayingTimes
+ - 날짜-상영시간 map 타입으로 가지고 있다.
+- Discount (인터페이스)
+ - calculate 메소드
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 4692cbe6e..6ec5d7122 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -43,4 +43,5 @@ dependencies {
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
+ implementation(project(":domain"))
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1ad1a01d9..f3fdad144 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -12,7 +12,13 @@
android:theme="@style/Theme.Movie"
tools:targetApi="31">
+
+
@@ -22,4 +28,4 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/java/woowacourse/movie/MainActivity.kt b/app/src/main/java/woowacourse/movie/MainActivity.kt
deleted file mode 100644
index 215e97c4d..000000000
--- a/app/src/main/java/woowacourse/movie/MainActivity.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package woowacourse.movie
-
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
-
-class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- }
-}
diff --git a/app/src/main/java/woowacourse/movie/activity/moviedetail/DateSpinnerListener.kt b/app/src/main/java/woowacourse/movie/activity/moviedetail/DateSpinnerListener.kt
new file mode 100644
index 000000000..92335007d
--- /dev/null
+++ b/app/src/main/java/woowacourse/movie/activity/moviedetail/DateSpinnerListener.kt
@@ -0,0 +1,21 @@
+package woowacourse.movie.activity.moviedetail
+
+import android.R
+import android.view.View
+import android.widget.AdapterView
+import android.widget.ArrayAdapter
+import android.widget.Spinner
+import woowacourse.movie.util.getKeyFromIndex
+import woowacourse.movie.util.getOrEmptyList
+import java.time.LocalDate
+import java.time.LocalTime
+
+class DateSpinnerListener(private val playingTimes: Map>, private val spinnerTime: Spinner) : AdapterView.OnItemSelectedListener {
+ override fun onItemSelected(adapterView: AdapterView<*>?, view: View?, index: Int, p3: Long) {
+ val times = playingTimes.getOrEmptyList(playingTimes.getKeyFromIndex(index))
+ spinnerTime.adapter = ArrayAdapter(spinnerTime.context, R.layout.simple_spinner_item, times)
+ }
+
+ override fun onNothingSelected(p0: AdapterView<*>?) {
+ }
+}
diff --git a/app/src/main/java/woowacourse/movie/activity/moviedetail/MovieDetailActivity.kt b/app/src/main/java/woowacourse/movie/activity/moviedetail/MovieDetailActivity.kt
new file mode 100644
index 000000000..4d88d804e
--- /dev/null
+++ b/app/src/main/java/woowacourse/movie/activity/moviedetail/MovieDetailActivity.kt
@@ -0,0 +1,57 @@
+package woowacourse.movie.activity.moviedetail
+
+import android.os.Bundle
+import android.view.MenuItem
+import android.widget.Spinner
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import woowacourse.movie.R
+import woowacourse.movie.model.MovieModel
+import woowacourse.movie.util.getSerializableExtraCompat
+
+class MovieDetailActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_movie_detail)
+ val movie: MovieModel? = intent.getSerializableExtraCompat(MOVIE_KEY)
+ if (movie == null) {
+ Toast.makeText(this, DATA_LOADING_ERROR_MESSAGE, Toast.LENGTH_LONG).show()
+ finish()
+ return
+ }
+ MovieDetailView(findViewById(R.id.layout_detail_info)).set(movie)
+ ReservationInfoView(findViewById(R.id.layout_reservation_info)).set(savedInstanceState, movie)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ return when (item.itemId) {
+ android.R.id.home -> {
+ finish()
+ true
+ }
+ else -> {
+ super.onOptionsItemSelected(item)
+ }
+ }
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ val countText = findViewById(R.id.text_count)
+ val spinnerDate = findViewById(R.id.spinner_date)
+ val spinnerTime = findViewById(R.id.spinner_time)
+ outState.putInt(COUNT_KEY, countText.text.toString().toInt())
+ outState.putInt(SPINNER_DATE_KEY, spinnerDate.selectedItemPosition)
+ outState.putInt(SPINNER_TIME_KEY, spinnerTime.selectedItemPosition)
+ }
+
+ companion object {
+ private const val DATA_LOADING_ERROR_MESSAGE = "데이터가 로딩되지 않았습니다. 다시 시도해주세요."
+ const val MOVIE_KEY = "MOVIE"
+ const val COUNT_KEY = "COUNT"
+ const val SPINNER_DATE_KEY = "SPINNER_DATE"
+ const val SPINNER_TIME_KEY = "SPINNER_TIME"
+ }
+}
diff --git a/app/src/main/java/woowacourse/movie/activity/moviedetail/MovieDetailView.kt b/app/src/main/java/woowacourse/movie/activity/moviedetail/MovieDetailView.kt
new file mode 100644
index 000000000..0323842b5
--- /dev/null
+++ b/app/src/main/java/woowacourse/movie/activity/moviedetail/MovieDetailView.kt
@@ -0,0 +1,43 @@
+package woowacourse.movie.activity.moviedetail
+
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import woowacourse.movie.R
+import woowacourse.movie.model.MovieModel
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+class MovieDetailView(private val viewGroup: ViewGroup) {
+ fun set(movie: MovieModel) {
+ setImageView(movie.image)
+ setTitle(movie.title)
+ setPlayingDate(movie.startDate, movie.endDate)
+ setRunningTime(movie.runningTime)
+ setDescription(movie.description)
+ }
+
+ private fun setDescription(description: String) {
+ viewGroup.findViewById(R.id.text_description).text = description
+ }
+
+ private fun setRunningTime(runningTime: Int) {
+ viewGroup.findViewById(R.id.text_running_time).text = viewGroup.context.getString(R.string.running_time, runningTime)
+ }
+
+ private fun setPlayingDate(startDate: LocalDate, endDate: LocalDate) {
+ viewGroup.findViewById(R.id.text_playing_date).text = viewGroup.context.getString(
+ R.string.playing_date_range,
+ DateTimeFormatter.ofPattern(viewGroup.context.getString(R.string.date_format)).format(startDate),
+ DateTimeFormatter.ofPattern(viewGroup.context.getString(R.string.date_format)).format(endDate)
+ )
+ }
+
+ private fun setTitle(title: String) {
+ viewGroup.findViewById(R.id.text_title).text = title
+ }
+
+ private fun setImageView(image: Int) {
+ viewGroup.findViewById(R.id.img_movie).setImageResource(image)
+ }
+}
diff --git a/app/src/main/java/woowacourse/movie/activity/moviedetail/ReservationInfoView.kt b/app/src/main/java/woowacourse/movie/activity/moviedetail/ReservationInfoView.kt
new file mode 100644
index 000000000..580a24eef
--- /dev/null
+++ b/app/src/main/java/woowacourse/movie/activity/moviedetail/ReservationInfoView.kt
@@ -0,0 +1,107 @@
+package woowacourse.movie.activity.moviedetail
+
+import android.content.Intent
+import android.os.Bundle
+import android.view.ViewGroup
+import android.widget.ArrayAdapter
+import android.widget.Button
+import android.widget.Spinner
+import android.widget.TextView
+import woowacourse.movie.R
+import woowacourse.movie.activity.ticketresult.TicketResultActivity
+import woowacourse.movie.domain.policy.DiscountPolicies
+import woowacourse.movie.domain.ticket.Price
+import woowacourse.movie.domain.ticket.Ticket
+import woowacourse.movie.model.MovieModel
+import woowacourse.movie.model.toPresentation
+import woowacourse.movie.util.getKeyFromIndex
+import woowacourse.movie.util.getOrEmptyList
+import java.time.LocalDate
+import java.time.LocalTime
+
+class ReservationInfoView(private val viewGroup: ViewGroup) {
+
+ fun set(savedInstanceState: Bundle?, movie: MovieModel) {
+ val savedCount = savedInstanceState?.getInt(MovieDetailActivity.COUNT_KEY) ?: DEFAULT_COUNT
+ val savedDate =
+ savedInstanceState?.getInt(MovieDetailActivity.SPINNER_DATE_KEY) ?: DEFAULT_POSITION
+ val savedTime =
+ savedInstanceState?.getInt(MovieDetailActivity.SPINNER_TIME_KEY) ?: DEFAULT_POSITION
+
+ setCount(savedCount)
+ setMinusButton()
+ setPlusButton()
+ setReserveButton(movie.title)
+ setDateSpinner(savedDate, movie.playingDateTimes)
+ setTimeSpinner(
+ savedTime,
+ movie.playingDateTimes.getOrEmptyList(movie.playingDateTimes.getKeyFromIndex(savedDate))
+ )
+ }
+
+ private fun setReserveButton(title: String) {
+ viewGroup.findViewById