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