plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-kapt")
}
android {
namespace = "com.example.moving"
compileSdk = 34
defaultConfig {
applicationId = "com.example.moving"
minSdk = 29
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
viewBinding = true
}
}
dependencies {
// Support
// https://developer.android.com/jetpack/androidx/versions
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.cardview:cardview:1.0.0")
// ViewModel and LiveData
// https://developer.android.com/jetpack/androidx/releases/lifecycle
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
// Retrofit
// https://github.com/square/retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
// Gson
// https://github.com/google/gson
implementation("com.google.code.gson:gson:2.10.1")
// Glide
// https://github.com/bumptech/glide
implementation("com.github.bumptech.glide:glide:4.16.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.3")
implementation("androidx.navigation:navigation-ui-ktx:2.7.3")
kapt("com.github.bumptech.glide:compiler:4.10.0")
// Testing
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test:runner:1.5.2")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
implementation("com.google.android.material:material:1.10.0")
implementation("com.github.antonKozyriatskyi:CircularProgressIndicator:1.3.0")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
}
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Moving"
tools:targetApi="31">
<activity
android:name=".SplashActivity"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".detail.MovieDetailsActivity"></activity>
<activity
android:name=".MainActivity"
android:exported="true" />
<activity
android:name=".signUp.SignUpActivity"
android:exported="true" />
<activity
android:name=".signIn.SignInActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<string name="main_fab_btn_description">FabBtn to add contact</string>
<string name="main_tab_title_contact">CONTACT</string>
<string name="main_tab_title_mypage">MY PAGE</string>
<string name="main_toolbar_title">무빙 출연진 연락처</string>
<string name="mypage_todo_edittext_hint">할일 추가하기</string>
<string name="mypage_todo_textview_title">할일 목록</string>
<string name="button_done">Log In</string>
<string name="button_done2">SIGN UP</string>
<string name="butotn_input">입력</string>
<string name="mypage_overlap_todo">이미 등록된 할일이 목록에 존재합니다.</string>
<string name="mypage_edittext_null">할일을 추가하시려면 텍스트를 입력해주세요!</string>
<string name="intent_userImage">userImage</string>
<string name="intent_userNameText">userName</string>
<string name="intent_userPositionText">userPosition</string>
<string name="intent_userTelText">userTel</string>
<string name="_5_10">5~10자의 영어(대소문자)와 숫자만 입력하세요.</string>
<string name="_8_15">8~15자의 영어(대소문자), 숫자, 특수문자를 포함하세요.</string>
<string name="_10_11">10~11자의 숫자만 입력하세요.</string>
<string name="kor">한글 또는 영어만 입력하세요.</string>
<string name="info">입력되지 않은 정보가 있습니다</string>
<string name="signup_cancel1">취소 되었습니다.</string>
//detail
<string name="warningBack">작성 중인 내용이 삭제될 수도 있습니다.</string>
<string name="warningNull">입력된 값이 없습니다.</string>
<string name="noticeComment">댓글을 입력하세요.</string>
<string name="comment">댓글</string>
//signIn
<string name="noticeTeam">Welcome Back!</string>
<string name="name">Full Name</string>
<string name="emailaddress">Email</string>
<string name="password">Password</string>
<string name="tel">TelPhone</string>
<string name="logIn">LOGIN</string>
<string name="signUp">SIGN UP</string>
<string name="checkNameLocale">이름/암호명을 확인해주세요</string>
<string name="successLogin">로그인 성공</string>
//writePage
<string name="subject">제목</string>
<string name="inputContents">내용을 입력해주세요</string>
<string name="cancel">취소</string>
//main
<string name="nameColon">이름 : </string>
<string name="position">Ability</string>
<string name="positionColon">직책 : </string>
<string name="teamMember">팀 멤버</string>
<string name="teamNoticeBoard">팀 게시판</string>
//signUp
<string name="notice2Team">SIGN UP</string>
<string name="inputName">이름을 입력하세요.</string>
<string name="inputID">이메일을 입력하세요.</string>
<string name="inputPassword">비밀번호를 입력하세요.</string>
<string name="inputPosition">(입력 안해도 됨)</string>
<string name="inputTel">전화번호를 입력하세요.</string>
<string name="locale">Locale</string>
<string name="inputLocale">지역명</string>
//dialog
<string name="dialog_name_edt">이름*</string>
<string name="dialog_phone_edt">전화번호*</string>
<string name="dialog_email_edt">이메일*</string>
<string name="dialog_locale_edt">지역*</string>
<string name="dialog_ability_edt">능력</string>
<string name="dialog_chip_off">OFF</string>
<string name="dialog_chip_5_minutes">5분 뒤 알림</string>
<string name="dialog_chip_10_minutes">10분 뒤 알림</string>
<string name="dialog_chip_30_minutes">30분 뒤 알림</string>
<string name="dialog_cancel_btn">취소</string>
<string name="dialog_add_btn">등록</string>
<string name="dialog_no_info_toast">* 표시가 있는 항목은 전부 입력해주세요.</string>
<string name="noti_title">연락처 알림</string>
<string name="noti_message">에게 연락을 할 시간입니다.</string>
<string name="title_activity_home">HomeActivity</string>
<string name="title_home2">Home</string>
<string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Search</string>
<string name="title_activity_main">MainActivity</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<fragment
android:id="@+id/navigation_home"
android:name="com.example.moving.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.example.moving.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" />
<fragment
android:id="@+id/navigation_notifications"
android:name="com.example.moving.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
<fragment
android:id="@+id/navigation_movie"
android:name="com.example.moving.ui.movie.MovieFragment"
android:label="@string/title_movie"
tools:layout="@layout/fragment_movie" />
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_tv_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_search_black_24dp"
android:title="@string/title_notifications" />
<item
android:id="@+id/navigation_movie"
android:icon="@drawable/ic_movie_black_24dp"
android:title="@string/title_movie" />
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
<fragment
android:id="@+id/nav_host_fragment_activity_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/movie_backdrop"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@+id/backdrop_guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.cardview.widget.CardView
android:id="@+id/movie_poster_card"
android:layout_width="128dp"
android:layout_height="172dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
app:cardCornerRadius="4dp"
app:layout_constraintBottom_toBottomOf="@+id/backdrop_guideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/backdrop_guideline">
<ImageView
android:id="@+id/movie_poster"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.cardview.widget.CardView>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/backdrop_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.4" />
<TextView
android:id="@+id/movie_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textColor="@android:color/white"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/movie_poster_card"
app:layout_constraintTop_toBottomOf="@+id/backdrop_guideline" />
<TextView
android:id="@+id/movie_release_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#757575"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/movie_title"
app:layout_constraintTop_toBottomOf="@+id/movie_title" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/movie_poster_title_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="movie_rating,movie_release_date" />
<TextView
android:id="@+id/movie_overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/movie_poster_title_barrier" />
<RatingBar
android:id="@+id/movie_rating"
style="@style/Widget.AppCompat.RatingBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="@+id/movie_poster_card"
app:layout_constraintStart_toStartOf="@+id/movie_poster_card"
app:layout_constraintTop_toBottomOf="@+id/movie_poster_card" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#212832"
android:orientation="vertical"
android:padding="0dp">
<ImageView
android:id="@+id/login_glide"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/logo_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:gravity="center"
android:padding="20dp"
android:src="@drawable/login_moving_logo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txt_login_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="26dp"
android:text="이름"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/logo_login" />
<EditText
android:id="@+id/et_login_name"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginHorizontal="20dp"
android:background="#4D455A64"
android:hint="@string/inputName"
android:inputType="text"
android:padding="16dp"
android:textColor="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/txt_login_name" />
<TextView
android:id="@+id/txt_login_locale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="26dp"
android:text="지역명"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_login_name" />
<EditText
android:id="@+id/et_login_locale"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginHorizontal="20dp"
android:layout_marginBottom="32dp"
android:background="#4D455A64"
android:hint="지역명을 입력해주세요."
android:inputType="textPassword"
android:padding="16dp"
android:textColor="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/txt_login_locale" />
<TextView
android:id="@+id/buttonLogin"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="60dp"
android:background="#99FED36A"
android:gravity="center"
android:text="@string/logIn"
android:textSize="20dp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/buttonSignUp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_login_locale" />
<TextView
android:id="@+id/buttonSignUp"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="26dp"
android:layout_marginBottom="26dp"
android:background="#991F63AA"
android:gravity="center"
android:text="@string/signUp"
android:textSize="20dp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonLogin" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/notice2Team"
android:textColor="#FFFFFF"
android:textSize="35sp"
android:textStyle="bold"
tools:layout_editor_absoluteX="-24dp"
tools:layout_editor_absoluteY="16dp" />
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text="@string/name"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<EditText
android:id="@+id/et_name"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="24dp"
android:background="#455A64"
android:ems="10"
android:hint="@string/inputName"
android:inputType="text"
android:padding="12dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_name" />
<TextView
android:id="@+id/tv_locale"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/locale"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_pw" />
<EditText
android:id="@+id/et_locale"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="24dp"
android:background="#455A64"
android:ems="10"
android:hint="@string/inputLocale"
android:inputType="text"
android:padding="12dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_locale" />
<TextView
android:id="@+id/tv_ability"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/position"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_locale" />
<EditText
android:id="@+id/et_ability"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="24dp"
android:background="#455A64"
android:ems="10"
android:hint="@string/inputPosition"
android:inputType="text"
android:padding="12dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_ability" />
<TextView
android:id="@+id/tv_emailaddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/emailaddress"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_name" />
<EditText
android:id="@+id/et_emailaddress"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="24dp"
android:background="#455A64"
android:ems="10"
android:hint="@string/inputID"
android:inputType="text"
android:padding="12dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_emailaddress" />
<TextView
android:id="@+id/tv_pw"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="24dp"
android:text="@string/password"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_emailaddress" />
<EditText
android:id="@+id/et_pw"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="24dp"
android:background="#455A64"
android:ems="10"
android:hint="@string/inputPassword"
android:inputType="textPassword"
android:padding="12dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_pw" />
<TextView
android:id="@+id/tv_tel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/tel"
android:textColor="#8CAAB9"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_ability" />
<EditText
android:id="@+id/et_tel"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="24dp"
android:background="#455A64"
android:ems="10"
android:hint="@string/inputTel"
android:inputType="number"
android:padding="12dp"
android:textColor="#FFFFFF"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_tel" />
<TextView
android:id="@+id/btn_signupOk"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="26dp"
android:layout_marginEnd="24dp"
android:background="#FED36A"
android:gravity="center"
android:text="@string/button_done2"
android:textSize="20dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_tel" />
<TextView
android:id="@+id/btn_signupcancel"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginTop="26dp"
android:background="@color/login_blue"
android:gravity="center"
android:text="Already have an account? LOGIN"
android:textSize="20dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/btn_signupOk"
app:layout_constraintStart_toStartOf="@+id/btn_signupOk"
app:layout_constraintTop_toBottomOf="@+id/btn_signupOk" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SplashActivity">
<ImageView
android:id="@+id/image_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:scaleType="centerCrop"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.dashboard.DashboardFragment">
<TextView
android:id="@+id/text_dashboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/popular"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/most_popular_tv" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/popular_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/toprated"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/most_toprated_tv" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/top_rated_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/on_the_air"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/on_the_air" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/on_the_air_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout3">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/airing_today"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/airing_today" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/airing_today_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout4">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/discover"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/discover" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/discover_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@+id/linearLayout5">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="\n\n\n\n"
tools:layout_editor_absoluteX="9dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.movie.MovieFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/popular"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/most_popular" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/popular_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/toprated"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/most_toprated" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/top_rated_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/upcoming"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/upcoming" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/upcoming_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout3">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/now_playing"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/now_playing" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/nowplaying_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout4">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/discover"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/discover" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/discover_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@+id/linearLayout5">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="\n\n\n\n"
tools:layout_editor_absoluteX="9dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.notifications.NotificationsFragment">
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="1dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="검색어"
android:textAlignment="center"
android:textSize="20sp" />
<EditText
android:id="@+id/eSearchWord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
android:text="" />
<Button
android:id="@+id/bSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="검색" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="Movie"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="영화 검색 결과" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="TV"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="TV 검색 결과" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="128dp"
android:layout_height="192dp"
android:layout_marginEnd="8dp"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/item_movie_poster"
android:layout_width="match_parent"
android:layout_height="172dp" />
<TextView
android:id="@+id/item_movie_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="128dp"
android:layout_height="192dp"
android:layout_marginEnd="8dp"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/item_tv_poster"
android:layout_width="match_parent"
android:layout_height="172dp" />
<TextView
android:id="@+id/item_tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title" />
</LinearLayout>
</androidx.cardview.widget.CardView>
package com.example.moving
import com.google.gson.annotations.SerializedName
data class GetTVResponse (
@SerializedName("page") val page: Int,
@SerializedName("results") val tvlist: List,
@SerializedName("totla_pages") val pages: Int,
@SerializedName("totla_results") val results: Int
)
package com.example.moving
import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.moving.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(setOf(R.id.navigation_movie, R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
companion object {
const val MOVIE_BACKDROP = "extra_movie_backdrop"
const val MOVIE_POSTER = "extra_movie_poster"
const val MOVIE_TITLE = "extra_movie_title"
const val MOVIE_RATING = "extra_movie_rating"
const val MOVIE_RELEASE_DATE = "extra_movie_release_date"
const val MOVIE_OVERVIEW = "extra_movie_overview"
}
}
package com.example.moving
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.example.moving.common.Movie
class MoviesAdapter (var movies: MutableList, var onMovieClick: (movie: Movie) -> Unit
) : RecyclerView.Adapter<MoviesAdapter.MovieViewHolder>(){
inner class MovieViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val poster: ImageView = itemView.findViewById(R.id.item_movie_poster)
fun bind(movie: Movie) {
Glide.with(itemView)
.load("https://image.tmdb.org/t/p/w342${movie.poster_path}")
.transform(CenterCrop())
.into(poster)
itemView.findViewById<TextView>(R.id.item_movie_title).text = movie.title
itemView.setOnClickListener { onMovieClick.invoke(movie) }
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.item_movie, parent, false)
return MovieViewHolder(view)
}
override fun getItemCount(): Int = movies.size
override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
holder.bind(movies[position])
}
fun appendMovies(movies: List<Movie>) {
this.movies.addAll(movies)
notifyItemRangeInserted(
this.movies.size,
movies.size - 1
)
}
fun removeMovies(movies: List<Movie>) {
this.movies.removeAll(movies)
}
}
package com.example.moving
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.example.moving.databinding.ActivitySplashBinding
import com.example.moving.signIn.SignInActivity
class SplashActivity : AppCompatActivity() {
lateinit var binding: ActivitySplashBinding
override fun onCreate(savedInstanceState: Bundle?) {
binding = ActivitySplashBinding.inflate(layoutInflater)
super.onCreate(savedInstanceState)
setContentView(binding.root)
val splashImage = binding.imageSplash
Glide.with(this).load(R.raw.splash_background).into(splashImage)
splashImage.setOnClickListener {
startActivity(Intent(this, SignInActivity::class.java))
}
}
}
package com.example.moving
import com.google.gson.annotations.SerializedName
data class TV (
@SerializedName("id")
val id : Long,
@SerializedName("name")
val name : String,
@SerializedName("overview")
val overview : String,
@SerializedName("poster_path")
val poster_path: String,
@SerializedName("backdrop_path")
val backdrop_path: String,
@SerializedName("vote_average")
val rating: Float,
@SerializedName("vote_count")
val vcount: Long,
@SerializedName("first_air_date")
val first_air_date: String,
@SerializedName("popularity")
val prating: Float
)
package com.example.moving
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
class TVAdapter (var tvlist: MutableList, var onTVClick: (tv: TV) -> Unit
) : RecyclerView.Adapter<TVAdapter.TvViewHolder>(){
inner class TvViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val poster: ImageView = itemView.findViewById(R.id.item_tv_poster)
fun bind(tv: TV) {
Glide.with(itemView)
.load("https://image.tmdb.org/t/p/w342${tv.poster_path}")
.transform(CenterCrop())
.into(poster)
itemView.findViewById<TextView>(R.id.item_tv_title).text = tv.name
itemView.setOnClickListener { onTVClick.invoke(tv) }
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TvViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.item_tv, parent, false)
return TvViewHolder(view)
}
override fun getItemCount(): Int = tvlist.size
override fun onBindViewHolder(holder: TvViewHolder, position: Int) {
holder.bind(tvlist[position])
}
fun appendTV(tvlist: List<TV>) {
this.tvlist.addAll(tvlist)
notifyItemRangeInserted(
this.tvlist.size,
tvlist.size - 1
)
}
fun removeTV(tvlist: List<TV>) {
this.tvlist.removeAll(tvlist)
}
}
package com.example.moving
import com.example.moving.common.Api
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object TVRepository {
private val api: Api //인터페이스 구현
init {
val retrofit = Retrofit.Builder()
.baseUrl("https://api.themoviedb.org/3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
api = retrofit.create(Api::class.java)
}
fun getPopularTV(page: Int = 1,
onSuccess: (tvlist: List<TV>) -> Unit,
onError: () -> Unit ) {
TVRepository.api.getPopularTV(page = page)
.enqueue(object : Callback<GetTVResponse> {
override fun onResponse(
call: Call<GetTVResponse>,
response: Response<GetTVResponse>
) {
if (response.isSuccessful) {
val responseBody = response.body()
if (responseBody != null) {
onSuccess.invoke(responseBody.tvlist)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetTVResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getTopRatedTV(page: Int = 1,
onSuccess: (tvlist: List<TV>) -> Unit,
onError: () -> Unit){
api.getTopRatedTV(page = page)
.enqueue(object : Callback<GetTVResponse> {
override fun onResponse(
call: Call<GetTVResponse>,
response: Response<GetTVResponse>
) {
if(response.isSuccessful) {
val responseBody = response.body()
if(responseBody != null) {
onSuccess.invoke(responseBody.tvlist)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetTVResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getOnTheAirTV(page: Int = 1,
onSuccess: (tvlist: List<TV>) -> Unit,
onError: () -> Unit){
api.getOnTheAirTV(page = page)
.enqueue(object : Callback<GetTVResponse> {
override fun onResponse(
call: Call<GetTVResponse>,
response: Response<GetTVResponse>
) {
if(response.isSuccessful) {
val responseBody = response.body()
if(responseBody != null) {
onSuccess.invoke(responseBody.tvlist)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetTVResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getAiringTodayTV(page: Int = 1,
onSuccess: (tvlist: List<TV>) -> Unit,
onError: () -> Unit){
api.getAiringTodayTV(page = page)
.enqueue(object : Callback<GetTVResponse> {
override fun onResponse(
call: Call<GetTVResponse>,
response: Response<GetTVResponse>
) {
if(response.isSuccessful) {
val responseBody = response.body()
if(responseBody != null) {
onSuccess.invoke(responseBody.tvlist)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetTVResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getDiscoverTV(page: Int = 1,
onSuccess: (tvlist: List<TV>) -> Unit,
onError: () -> Unit){
api.getDiscoverTV(page = page)
.enqueue(object : Callback<GetTVResponse> {
override fun onResponse(
call: Call<GetTVResponse>,
response: Response<GetTVResponse>
) {
if(response.isSuccessful) {
val responseBody = response.body()
if(responseBody != null) {
onSuccess.invoke(responseBody.tvlist)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetTVResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getSearchTV(page: Int = 1, query: String,
onSuccess: (tvlist: List<TV>) -> Unit,
onError: () -> Unit){
api.getSearchTV(page = page, query = query)
.enqueue(object : Callback<GetTVResponse> {
override fun onResponse(
call: Call<GetTVResponse>,
response: Response<GetTVResponse>
) {
if(response.isSuccessful) {
val responseBody = response.body()
if(responseBody != null) {
onSuccess.invoke(responseBody.tvlist)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetTVResponse>, t: Throwable) {
onError.invoke()
}
})
}
}
package com.example.moving.common
import com.example.moving.GetTVResponse
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query
interface Api {
@GET("movie/popular")
fun getPopularMovies(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page: Int,
@Query("language")
language : String = "ko,en-US"
): Call
@GET("movie/top_rated")
fun getTopRatedMovies(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetMoviesResponse>
@GET("movie/upcoming")
fun getUpcomingMovies(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetMoviesResponse>
@GET("movie/now_playing")
fun getNowPlayingMovies(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetMoviesResponse>
@GET("discover/movie")
fun getDiscoverMovies(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetMoviesResponse>
@GET("tv/popular")
fun getPopularTV(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetTVResponse>
@GET("tv/top_rated")
fun getTopRatedTV(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetTVResponse>
@GET("tv/on_the_air")
fun getOnTheAirTV(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetTVResponse>
@GET("tv/airing_today")
fun getAiringTodayTV(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetTVResponse>
@GET("discover/tv")
fun getDiscoverTV(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("language")
language : String = "ko,en-US"
): Call<GetTVResponse>
@GET("search/movie")
fun getSearchMovies(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("query")
query : String,
@Query("language")
language : String = "ko,en-US"
): Call<GetMoviesResponse>
@GET("search/tv")
fun getSearchTV(
@Query("api_key")
apiKey: String = "9897e125444076b7172d70bff4fe9c5d",
@Query("page")
page : Int,
@Query("query")
query : String,
@Query("language")
language : String = "ko,en-US"
): Call<GetTVResponse>
}
package com.example.moving.common
import com.google.gson.annotations.SerializedName
data class GetMoviesResponse(
@SerializedName("page")
val page: Int,
@SerializedName("results")
val movies: List,
@SerializedName("total_pages")
val pages: Int,
@SerializedName("total_results")
val results: Int
)
package com.example.moving.common
import com.google.gson.annotations.SerializedName
data class Movie(
@SerializedName("id")
val id : Long,
@SerializedName("title")
val title : String,
@SerializedName("overview")
val overview : String,
@SerializedName("poster_path")
val poster_path: String,
@SerializedName("backdrop_path")
val backdrop_path: String,
@SerializedName("vote_average")
val rating: Float,
@SerializedName("vote_count")
val vcount: Long,
@SerializedName("release_date")
val releaseDate: String,
@SerializedName("popularity")
val prating: Float
)
package com.example.moving.common
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object MoviesRepository {
private val api: Api
init {
val retrofit = Retrofit.Builder()
.baseUrl("https://api.themoviedb.org/3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
api = retrofit.create(Api::class.java)
}
fun getPopularMovies(page: Int = 1,
onSuccess: (movies: List<Movie>) -> Unit,
onError: () -> Unit ) {
api.getPopularMovies(page = page)
.enqueue(object : Callback<GetMoviesResponse> {
override fun onResponse(
call: Call<GetMoviesResponse>,
response: Response<GetMoviesResponse>
) {
if (response.isSuccessful) {
val responseBody = response.body()
if (responseBody != null) {
onSuccess.invoke(responseBody.movies)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getTopRatedMovies(page: Int = 1,
onSuccess: (movies: List<Movie>) -> Unit,
onError: () -> Unit ) {
api.getTopRatedMovies(page = page)
.enqueue(object : Callback<GetMoviesResponse> {
override fun onResponse(
call: Call<GetMoviesResponse>,
response: Response<GetMoviesResponse>
) {
if (response.isSuccessful) {
val responseBody = response.body()
if (responseBody != null) {
onSuccess.invoke(responseBody.movies)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getUpcomingMovies( page: Int = 1,
onSuccess: (movies: List<Movie>) -> Unit,
onError: () -> Unit ) {
api.getUpcomingMovies(page = page)
.enqueue(object : Callback<GetMoviesResponse> {
override fun onResponse(
call: Call<GetMoviesResponse>,
response: Response<GetMoviesResponse>
) {
if (response.isSuccessful) {
val responseBody = response.body()
if (responseBody != null) {
onSuccess.invoke(responseBody.movies)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getNowPlayingMovies( page: Int = 1,
onSuccess: (movies: List<Movie>) -> Unit,
onError: () -> Unit ) {
api.getNowPlayingMovies(page = page)
.enqueue(object : Callback<GetMoviesResponse> {
override fun onResponse(
call: Call<GetMoviesResponse>,
response: Response<GetMoviesResponse>
) {
if (response.isSuccessful) {
val responseBody = response.body()
if (responseBody != null) {
onSuccess.invoke(responseBody.movies)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getDiscoverMovies( page: Int = 1,
onSuccess: (movies: List<Movie>) -> Unit,
onError: () -> Unit ) {
api.getDiscoverMovies(page = page)
.enqueue(object : Callback<GetMoviesResponse> {
override fun onResponse(
call: Call<GetMoviesResponse>,
response: Response<GetMoviesResponse>
) {
if (response.isSuccessful) {
val responseBody = response.body()
if (responseBody != null) {
onSuccess.invoke(responseBody.movies)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t: Throwable) {
onError.invoke()
}
})
}
fun getSearchMovies( page: Int = 1, query: String,
onSuccess: (movies: List<Movie>) -> Unit,
onError: () -> Unit ) {
api.getSearchMovies(page = page, query = query)
.enqueue(object : Callback<GetMoviesResponse> {
override fun onResponse(
call: Call<GetMoviesResponse>,
response: Response<GetMoviesResponse>
) {
if (response.isSuccessful) {
val responseBody = response.body()
if (responseBody != null) {
onSuccess.invoke(responseBody.movies)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t: Throwable) {
onError.invoke()
}
})
}
}
package com.example.moving.detail
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.example.moving.MainActivity.Companion.MOVIE_BACKDROP
import com.example.moving.MainActivity.Companion.MOVIE_OVERVIEW
import com.example.moving.MainActivity.Companion.MOVIE_POSTER
import com.example.moving.MainActivity.Companion.MOVIE_RATING
import com.example.moving.MainActivity.Companion.MOVIE_RELEASE_DATE
import com.example.moving.MainActivity.Companion.MOVIE_TITLE
import com.example.moving.R
class MovieDetailsActivity : AppCompatActivity() {
private lateinit var backdrop: ImageView
private lateinit var poster: ImageView
private lateinit var title: TextView
private lateinit var rating: RatingBar
private lateinit var releaseDate: TextView
private lateinit var overview: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_movie_details)
backdrop = findViewById(R.id.movie_backdrop)
poster = findViewById(R.id.movie_poster)
title = findViewById(R.id.movie_title)
rating = findViewById(R.id.movie_rating)
releaseDate = findViewById(R.id.movie_release_date)
overview = findViewById(R.id.movie_overview)
val extras = intent.extras
if (extras != null) {
populateDetails(extras)
} else {
finish()
}
}
private fun populateDetails(extras: Bundle) {
extras.getString(MOVIE_BACKDROP)?.let { backdropPath ->
Glide.with(this)
.load("https://image.tmdb.org/t/p/w1280$backdropPath")
.transform(CenterCrop())
.into(backdrop)
}
extras.getString(MOVIE_POSTER)?.let { posterPath ->
Glide.with(this)
.load("https://image.tmdb.org/t/p/w342$posterPath")
.transform(CenterCrop())
.into(poster)
}
title.text = extras.getString(MOVIE_TITLE, "")
rating.rating = extras.getFloat(MOVIE_RATING, 0f) / 2
releaseDate.text = extras.getString(MOVIE_RELEASE_DATE, "")
overview.text = extras.getString(MOVIE_OVERVIEW, "")
}
}
package com.example.moving.signIn
import android.content.Intent
import android.os.Bundle
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.example.moving.R
import com.example.moving.MainActivity
import com.example.moving.signUp.SignUpActivity
class SignInActivity : AppCompatActivity() {
private lateinit var editTextName: EditText
private lateinit var editTextLocale: EditText
private lateinit var buttonLogin: TextView
private lateinit var buttonSignUp: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_in)
/*Glide 배경 움짤 추가 */
val loginGlide = findViewById<ImageView>(R.id.login_glide)
Glide.with(this).load(R.raw.login_background).into(loginGlide)
//
editTextName = findViewById(R.id.et_login_name)
editTextLocale = findViewById(R.id.et_login_locale)
buttonLogin = findViewById(R.id.buttonLogin)
buttonSignUp = findViewById(R.id.buttonSignUp)
buttonLogin.setOnClickListener {
val checkName = intent.getStringExtra("userName") ?: "name"
val checkEmailAddress = intent.getStringExtra("userEmailAddress") ?: "emailaddress"
val checkTel = intent.getStringExtra("userTel") ?: "tel"
val checkLocale = intent.getStringExtra("userLocale") ?: "locale"
val checkAbility = intent.getStringExtra("userAbility") ?: "ability"
val loginName = editTextName.text.toString() // 이름, 암호명으로 로그인 변경 작업
val loginLocale = editTextLocale.text.toString()
if (loginName.isEmpty() || loginLocale.isEmpty()) {
Toast.makeText(this, "이름/암호명 모두 입력해주세요.", Toast.LENGTH_SHORT).show()
} else if((loginName == checkName) && (loginLocale == checkLocale)){
Toast.makeText(this, R.string.successLogin, Toast.LENGTH_SHORT).show()
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("userName", checkName)
intent.putExtra("userEmailAddress", checkEmailAddress)
intent.putExtra("userTel", checkTel)
intent.putExtra("userAbility", checkAbility)
intent.putExtra("userLocale", checkLocale)
startActivity(intent)
finish()
} else{
Toast.makeText(this, R.string.checkNameLocale, Toast.LENGTH_SHORT).show()
}
}
buttonSignUp.setOnClickListener {
startActivity(Intent(this, SignUpActivity::class.java))
}
}
}
package com.example.moving.signUp
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
import com.example.moving.R
import com.example.moving.signIn.SignInActivity
import java.util.regex.Pattern
class SignUpActivity : AppCompatActivity() {
private val emailaddressPattern = Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)\$")
private val pwPattern = Pattern.compile("^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#\$%^&+=]).{8,15}\$")
private val localePattern = Pattern.compile("^[가-힣a-zA-Z]*\$")
private val namePattern = Pattern.compile("^[가-힣a-zA-Z]*\$")
private val telPattern = Pattern.compile("^[0-9]{10,11}\$")
private var imgSet: Int = R.drawable.logo1 // 기본 값으로 초기화
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_up)
val et_name = findViewById<EditText>(R.id.et_name)
val et_emailaddress = findViewById<EditText>(R.id.et_emailaddress)
val et_pw = findViewById<EditText>(R.id.et_pw)
val et_locale = findViewById<EditText>(R.id.et_locale)
val et_ability = findViewById<EditText>(R.id.et_ability)
val et_tel = findViewById<EditText>(R.id.et_tel)
val btn_signUp = findViewById<TextView>(R.id.btn_signupOk)
val btn_signCancel = findViewById<TextView>(R.id.btn_signupcancel)
et_emailaddress.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
val emailaddress = s.toString()
val valid = emailaddressPattern.matcher(emailaddress).matches()
if (!valid) {
et_emailaddress.error = getString(R.string._5_10)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
et_pw.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
val pw = s.toString()
val valid = pwPattern.matcher(pw).matches()
if (!valid) {
et_pw.error = getString(R.string._8_15)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
et_locale.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
val locale = s.toString()
val valid = localePattern.matcher(locale).matches()
if (!valid) {
et_locale.error = getString(R.string.kor)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
et_tel.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
val tel = s.toString()
val valid = telPattern.matcher(tel).matches()
if (!valid) {
et_tel.error = getString(R.string._10_11)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
et_name.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
val name = s.toString()
val valid = namePattern.matcher(name).matches()
if (!valid) {
et_name.error = getString(R.string.kor)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
//이미지 초기화
// val iv_logo = findViewById(R.id.imageView)
// iv_logo.setOnClickListener {
// imgSet = when ((1..6).random()) {
// 1 -> R.drawable.logo1
// 2 -> R.drawable.logo2
// 3 -> R.drawable.logo3
// 4 -> R.drawable.logo4
// 5 -> R.drawable.logo5
// else -> R.drawable.logo1
// }
//
// iv_logo.setImageDrawable(ResourcesCompat.getDrawable(resources, imgSet, null))
//
// }
btn_signUp.setOnClickListener{
val name = et_name.text.toString()
val emailaddress = et_emailaddress.text.toString()
val pw = et_pw.text.toString()
val locale = et_locale.text.toString()
val ability = et_ability.text.toString()
val tel = et_tel.text.toString()
if (name.isBlank() || emailaddress.isBlank() || pw.isBlank() || locale.isBlank() || tel.isBlank()) {
Toast.makeText(this, getString(R.string.info), Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val nameValid = namePattern.matcher(name).matches()
val emailaddressValid = emailaddressPattern.matcher(emailaddress).matches()
val pwValid = pwPattern.matcher(pw).matches()
val localeValid = localePattern.matcher(locale).matches()
val telValid = telPattern.matcher(tel).matches()
if (!nameValid) {
et_name.error = getString(R.string.kor)
return@setOnClickListener
}
if (!emailaddressValid) {
et_emailaddress.error = getString(R.string._5_10)
return@setOnClickListener
}
if (!pwValid) {
et_pw.error = getString(R.string._8_15)
return@setOnClickListener
}
if (!localeValid) {
et_locale.error = getString(R.string.kor)
return@setOnClickListener
}
if (!telValid) {
et_tel.error = getString(R.string._10_11)
return@setOnClickListener
}
val intent = Intent(this, SignInActivity::class.java)
//수정하겠습니다.
intent.putExtra("userName", name)
intent.putExtra("userEmailAddress", emailaddress)
intent.putExtra("userTel", tel)
intent.putExtra("userLocale", locale)
intent.putExtra("userAbility", ability)
startActivity(intent)
finish()
}
btn_signCancel.setOnClickListener {
Toast.makeText(this@SignUpActivity, "취소 되었습니다.", Toast.LENGTH_SHORT).show()
val intent = Intent(this@SignUpActivity, SignInActivity::class.java)
startActivity(intent)
finish()
}
}
}
package com.example.moving.ui.dashboard
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.moving.databinding.FragmentDashboardBinding
class DashboardFragment : Fragment() {
private var _binding: FragmentDashboardBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val dashboardViewModel =
ViewModelProvider(this).get(DashboardViewModel::class.java)
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textDashboard
dashboardViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
package com.example.moving.ui.dashboard
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class DashboardViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is dashboard Fragment"
}
val text: LiveData<String> = _text
}
package com.example.moving.ui.home
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.moving.MainActivity
import com.example.moving.R
import com.example.moving.TV
import com.example.moving.TVAdapter
import com.example.moving.TVRepository
import com.example.moving.databinding.FragmentHomeBinding
import com.example.moving.detail.MovieDetailsActivity
class HomeFragment : Fragment() {
lateinit var root : View
private lateinit var popularTV: RecyclerView
private lateinit var popularTVAdapter: TVAdapter
private lateinit var popularTVLayoutMgr: LinearLayoutManager
private var popularTVPage = 1
private lateinit var topRatedTV: RecyclerView
private lateinit var topRatedTVAdapter: TVAdapter
private lateinit var topRatedTVLayoutMgr: LinearLayoutManager
private var topRatedTVPage = 1
private lateinit var onTheAirTV: RecyclerView
private lateinit var onTheAirTVAdapter: TVAdapter
private lateinit var onTheAirTVLayoutMgr: LinearLayoutManager
private var onTheAirTVPage = 1
private lateinit var airingTodayTV: RecyclerView
private lateinit var airingTodayTVAdapter: TVAdapter
private lateinit var airingTodayTVLayoutMgr: LinearLayoutManager
private var airingTodayTVPage = 1
private lateinit var discoverTV: RecyclerView
private lateinit var discoverTVAdapter: TVAdapter
private lateinit var discoverTVLayoutMgr: LinearLayoutManager
private var discoverTVPage = 1
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? ): View? {
root = inflater.inflate(R.layout.fragment_home, container, false)
popularTV = root.findViewById(R.id.popular_tv)
popularTVLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
popularTV.layoutManager = popularTVLayoutMgr
popularTVAdapter = TVAdapter(mutableListOf()) { tv -> showTVDetails(tv) }
popularTV.adapter = popularTVAdapter
getPopularTV()
topRatedTV = root.findViewById(R.id.top_rated_tv)
topRatedTVLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
topRatedTV.layoutManager = topRatedTVLayoutMgr
topRatedTVAdapter = TVAdapter(mutableListOf()) { tv -> showTVDetails(tv) }
topRatedTV.adapter = topRatedTVAdapter
getTopRatedTV()
onTheAirTV = root.findViewById(R.id.on_the_air_tv)
onTheAirTVLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
onTheAirTV.layoutManager = onTheAirTVLayoutMgr
onTheAirTVAdapter = TVAdapter(mutableListOf()) { tv -> showTVDetails(tv) }
onTheAirTV.adapter = onTheAirTVAdapter
getOnTheAirTV()
airingTodayTV = root.findViewById(R.id.airing_today_tv)
airingTodayTVLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
airingTodayTV.layoutManager = airingTodayTVLayoutMgr
airingTodayTVAdapter = TVAdapter(mutableListOf()) { tv -> showTVDetails(tv) }
airingTodayTV.adapter = airingTodayTVAdapter
getAiringTodayTV()
discoverTV = root.findViewById(R.id.discover_tv)
discoverTVLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
discoverTV.layoutManager = discoverTVLayoutMgr
discoverTVAdapter = TVAdapter(mutableListOf()) { tv -> showTVDetails(tv) }
discoverTV.adapter = discoverTVAdapter
getDiscoverTV()
return root
}
private fun getPopularTV() {
TVRepository.getPopularTV(
popularTVPage,
::onPopularTVFetched,
::onError
)
}
private fun onPopularTVFetched(tvlist: List<TV>) {
popularTVAdapter.appendTV(tvlist)
attachPopularTVOnScrollListener()
}
private fun attachPopularTVOnScrollListener() {
popularTV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = popularTVLayoutMgr.itemCount
val visibleItemCount = popularTVLayoutMgr.childCount
val firstVisibleItem = popularTVLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
popularTV.removeOnScrollListener(this)
popularTVPage++
getPopularTV()
}
}
})
}
private fun getTopRatedTV() {
TVRepository.getTopRatedTV(
topRatedTVPage,
::onTopRatedTVFetched,
::onError
)
}
private fun onTopRatedTVFetched(tvlist: List<TV>) {
topRatedTVAdapter.appendTV(tvlist)
attachTopRatedTVOnScrollListener()
}
private fun attachTopRatedTVOnScrollListener() {
topRatedTV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = topRatedTVLayoutMgr.itemCount
val visibleItemCount = topRatedTVLayoutMgr.childCount
val firstVisibleItem = topRatedTVLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
topRatedTV.removeOnScrollListener(this)
topRatedTVPage++
getTopRatedTV()
}
}
})
}
private fun getOnTheAirTV() {
TVRepository.getOnTheAirTV(
onTheAirTVPage,
::onOnTheAirTVFetched,
::onError
)
}
private fun onOnTheAirTVFetched(tvlist: List<TV>) {
onTheAirTVAdapter.appendTV(tvlist)
attachOnTheAirTVOnScrollListener()
}
private fun attachOnTheAirTVOnScrollListener() {
onTheAirTV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = onTheAirTVLayoutMgr.itemCount
val visibleItemCount = onTheAirTVLayoutMgr.childCount
val firstVisibleItem = onTheAirTVLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
onTheAirTV.removeOnScrollListener(this)
onTheAirTVPage++
getOnTheAirTV()
}
}
})
}
private fun getAiringTodayTV() {
TVRepository.getAiringTodayTV(
airingTodayTVPage,
::onAiringTodayTVFetched,
::onError
)
}
private fun onAiringTodayTVFetched(tvlist: List<TV>) {
airingTodayTVAdapter.appendTV(tvlist)
attachAiringTodayTVOnScrollListener()
}
private fun attachAiringTodayTVOnScrollListener() {
airingTodayTV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = airingTodayTVLayoutMgr.itemCount
val visibleItemCount = airingTodayTVLayoutMgr.childCount
val firstVisibleItem = airingTodayTVLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
airingTodayTV.removeOnScrollListener(this)
airingTodayTVPage++
getAiringTodayTV()
}
}
})
}
private fun getDiscoverTV() {
TVRepository.getDiscoverTV(
discoverTVPage,
::onDiscoverTVFetched,
::onError
)
}
private fun onDiscoverTVFetched(tvlist: List<TV>) {
discoverTVAdapter.appendTV(tvlist)
attachDiscoverTVOnScrollListener()
}
private fun attachDiscoverTVOnScrollListener() {
discoverTV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = discoverTVLayoutMgr.itemCount
val visibleItemCount = discoverTVLayoutMgr.childCount
val firstVisibleItem = discoverTVLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
discoverTV.removeOnScrollListener(this)
discoverTVPage++
getDiscoverTV()
}
}
})
}
private fun onError() {
Toast.makeText(activity, "error Movies", Toast.LENGTH_SHORT).show()
}
private fun showTVDetails(tv: TV) {
val intent = Intent(activity, MovieDetailsActivity::class.java)
intent.putExtra(MainActivity.MOVIE_BACKDROP, tv.backdrop_path)
intent.putExtra(MainActivity.MOVIE_POSTER, tv.poster_path)
intent.putExtra(MainActivity.MOVIE_TITLE, tv.name)
intent.putExtra(MainActivity.MOVIE_RATING, tv.rating)
intent.putExtra(MainActivity.MOVIE_RELEASE_DATE, tv.first_air_date)
intent.putExtra(MainActivity.MOVIE_OVERVIEW, tv.overview)
startActivity(intent)
}
}
package com.example.moving.ui.home
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class HomeViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is home Fragment"
}
val text: LiveData<String> = _text
}
package com.example.moving.ui.movie
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.moving.MainActivity
import com.example.moving.MoviesAdapter
import com.example.moving.R
import com.example.moving.common.MoviesRepository
import com.example.moving.common.Movie
import com.example.moving.detail.MovieDetailsActivity
class MovieFragment : Fragment() {
lateinit var root: View
private lateinit var popularMovies: RecyclerView
private lateinit var popularMoviesAdapter: MoviesAdapter
private lateinit var popularMoviesLayoutMgr: LinearLayoutManager
private var popularMoviesPage = 1
private lateinit var topRatedMovies: RecyclerView
private lateinit var topRatedMoviesAdapter: MoviesAdapter
private lateinit var topRatedMoviesLayoutMgr: LinearLayoutManager
private var topRatedMoviesPage = 1
private lateinit var upcomingMovies: RecyclerView
private lateinit var upcomingMoviesAdapter: MoviesAdapter
private lateinit var upcomingMoviesLayoutMgr: LinearLayoutManager
private var upcomingMoviesPage = 1
private lateinit var nowplayingMovies: RecyclerView
private lateinit var nowplayingMoviesAdapter: MoviesAdapter
private lateinit var nowplayingMoviesLayoutMgr: LinearLayoutManager
private var nowplayingMoviesPage = 1
private lateinit var discoverMovies: RecyclerView
private lateinit var discoverMoviesAdapter: MoviesAdapter
private lateinit var discoverMoviesLayoutMgr: LinearLayoutManager
private var discoverMoviesPage = 1
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? ): View? {
root = inflater.inflate(R.layout.fragment_movie, container, false)
popularMovies = root.findViewById(R.id.popular_movies)
popularMoviesLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
popularMovies.layoutManager = popularMoviesLayoutMgr
popularMoviesAdapter = MoviesAdapter(mutableListOf()) { movie -> showMovieDetails(movie) }
popularMovies.adapter = popularMoviesAdapter
getPopularMovies()
topRatedMovies = root.findViewById(R.id.top_rated_movies)
topRatedMoviesLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
topRatedMovies.layoutManager = topRatedMoviesLayoutMgr
topRatedMoviesAdapter = MoviesAdapter(mutableListOf()) { movie -> showMovieDetails(movie) }
topRatedMovies.adapter = topRatedMoviesAdapter
getTopRatedMovies()
upcomingMovies = root.findViewById(R.id.upcoming_movies)
upcomingMoviesLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
upcomingMovies.layoutManager = upcomingMoviesLayoutMgr
upcomingMoviesAdapter = MoviesAdapter(mutableListOf()) { movie -> showMovieDetails(movie) }
upcomingMovies.adapter = upcomingMoviesAdapter
getUpcomingMovies()
nowplayingMovies = root.findViewById(R.id.nowplaying_movies)
nowplayingMoviesLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
nowplayingMovies.layoutManager = nowplayingMoviesLayoutMgr
nowplayingMoviesAdapter = MoviesAdapter(mutableListOf()) { movie -> showMovieDetails(movie) }
nowplayingMovies.adapter = nowplayingMoviesAdapter
getNowplayingMovies()
discoverMovies = root.findViewById(R.id.discover_movies)
discoverMoviesLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
discoverMovies.layoutManager = discoverMoviesLayoutMgr
discoverMoviesAdapter = MoviesAdapter(mutableListOf()) { movie -> showMovieDetails(movie) }
discoverMovies.adapter = discoverMoviesAdapter
getDiscoverMovies()
return root
}
private fun getPopularMovies() {
MoviesRepository.getPopularMovies(
popularMoviesPage,
::onPopularMoviesFetched,
::onError
)
}
private fun onPopularMoviesFetched(movies: List<Movie>) {
popularMoviesAdapter.appendMovies(movies)
attachPopularMoviesOnScrollListener()
}
private fun attachPopularMoviesOnScrollListener() {
popularMovies.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = popularMoviesLayoutMgr.itemCount
val visibleItemCount = popularMoviesLayoutMgr.childCount
val firstVisibleItem = popularMoviesLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
popularMovies.removeOnScrollListener(this)
popularMoviesPage++
getPopularMovies()
}
}
})
}
private fun getTopRatedMovies() {
MoviesRepository.getTopRatedMovies(
topRatedMoviesPage,
::onTopRatedMoviesFetched,
::onError
)
}
private fun attachTopRatedMoviesOnScrollListener() {
topRatedMovies.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = topRatedMoviesLayoutMgr.itemCount
val visibleItemCount = topRatedMoviesLayoutMgr.childCount
val firstVisibleItem = topRatedMoviesLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
topRatedMovies.removeOnScrollListener(this)
topRatedMoviesPage++
getTopRatedMovies()
}
}
})
}
private fun onTopRatedMoviesFetched(movies: List<Movie>) {
topRatedMoviesAdapter.appendMovies(movies)
attachTopRatedMoviesOnScrollListener()
}
private fun getUpcomingMovies() {
MoviesRepository.getUpcomingMovies(
upcomingMoviesPage,
::onUpcomingMoviesFetched,
::onError
)
}
private fun attachUpcomingMoviesOnScrollListener() {
upcomingMovies.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = upcomingMoviesLayoutMgr.itemCount
val visibleItemCount = upcomingMoviesLayoutMgr.childCount
val firstVisibleItem = upcomingMoviesLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
upcomingMovies.removeOnScrollListener(this)
upcomingMoviesPage++
getUpcomingMovies()
}
}
})
}
private fun onUpcomingMoviesFetched(movies: List<Movie>) {
upcomingMoviesAdapter.appendMovies(movies)
attachUpcomingMoviesOnScrollListener()
}
private fun getNowplayingMovies() {
MoviesRepository.getNowPlayingMovies(
nowplayingMoviesPage,
::onNowplayingMoviesFetched,
::onError
)
}
private fun attachNowplayingMoviesOnScrollListener() {
nowplayingMovies.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = nowplayingMoviesLayoutMgr.itemCount
val visibleItemCount = nowplayingMoviesLayoutMgr.childCount
val firstVisibleItem = nowplayingMoviesLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
nowplayingMovies.removeOnScrollListener(this)
nowplayingMoviesPage++
getNowplayingMovies()
}
}
})
}
private fun onNowplayingMoviesFetched(movies: List<Movie>) {
nowplayingMoviesAdapter.appendMovies(movies)
attachNowplayingMoviesOnScrollListener()
}
private fun getDiscoverMovies() {
MoviesRepository.getDiscoverMovies(
discoverMoviesPage,
::onDiscoverMoviesFetched,
::onError
)
}
private fun attachDiscoverMoviesOnScrollListener() {
discoverMovies.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = discoverMoviesLayoutMgr.itemCount
val visibleItemCount = discoverMoviesLayoutMgr.childCount
val firstVisibleItem = discoverMoviesLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
discoverMovies.removeOnScrollListener(this)
discoverMoviesPage++
getDiscoverMovies()
}
}
})
}
private fun onDiscoverMoviesFetched(movies: List<Movie>) {
discoverMoviesAdapter.appendMovies(movies)
attachDiscoverMoviesOnScrollListener()
}
private fun onError() {
Toast.makeText(activity, "error Movies", Toast.LENGTH_SHORT).show()
}
private fun showMovieDetails(movie: Movie) {
val intent = Intent(activity, MovieDetailsActivity::class.java)
intent.putExtra(MainActivity.MOVIE_BACKDROP, movie.backdrop_path)
intent.putExtra(MainActivity.MOVIE_POSTER, movie.poster_path)
intent.putExtra(MainActivity.MOVIE_TITLE, movie.title)
intent.putExtra(MainActivity.MOVIE_RATING, movie.rating)
intent.putExtra(MainActivity.MOVIE_RELEASE_DATE, movie.releaseDate)
intent.putExtra(MainActivity.MOVIE_OVERVIEW, movie.overview)
startActivity(intent)
}
}
package com.example.moving.ui.notifications
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.moving.MainActivity
import com.example.moving.MoviesAdapter
import com.example.moving.R
import com.example.moving.TV
import com.example.moving.TVAdapter
import com.example.moving.TVRepository
import com.example.moving.common.MoviesRepository
import com.example.moving.databinding.FragmentNotificationsBinding
import com.example.moving.detail.MovieDetailsActivity
import com.example.moving.common.Movie
class NotificationsFragment : Fragment() {
lateinit var root : View
var searchKeyword = ""
private lateinit var searchMovies: RecyclerView
private lateinit var searchMoviesAdapter: MoviesAdapter
private lateinit var searchMoviesLayoutMgr: LinearLayoutManager
private var searchMoviesPage = 1
private lateinit var searchTV: RecyclerView
private lateinit var searchTVAdapter: TVAdapter
private lateinit var searchTVLayoutMgr: LinearLayoutManager
private var searchTVPage = 1
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? ): View? {
root = inflater.inflate(R.layout.fragment_notifications, container, false)
val searchButton = root.findViewById<Button>(R.id.bSearch)
val searchInputField = root.findViewById<EditText>(R.id.eSearchWord)
searchMovies = root.findViewById(R.id.search_movies)
searchMoviesLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
searchMovies.layoutManager = searchMoviesLayoutMgr
searchMoviesAdapter = MoviesAdapter(mutableListOf()) { movie -> showMovieDetails(movie) }
searchMovies.adapter = searchMoviesAdapter
searchTV = root.findViewById(R.id.search_tv)
searchTVLayoutMgr = LinearLayoutManager(
context,
LinearLayoutManager.HORIZONTAL,
false
)
searchTV.layoutManager = searchTVLayoutMgr
searchTVAdapter = TVAdapter(mutableListOf()) { tv -> showTVDetails(tv) }
searchTV.adapter = searchTVAdapter
searchButton.setOnClickListener {
searchKeyword = searchInputField.text.toString()
if(searchKeyword == "") {
Toast.makeText(activity, "input keyword", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(activity, searchKeyword, Toast.LENGTH_SHORT).show()
getSearchMovies()
getPopularTV()
}
}
return root
}
private fun removeData() {
searchMovies.removeAllViews()
searchTV.removeAllViews()
searchMoviesAdapter.removeMovies(searchMoviesAdapter.movies)
searchMoviesAdapter.notifyDataSetChanged()
searchTVAdapter.removeTV(searchTVAdapter.tvlist)
searchTVAdapter.notifyDataSetChanged()
}
private fun getSearchMovies() {
MoviesRepository.getSearchMovies(
searchMoviesPage,
searchKeyword,
::onSearchMoviesFetched,
::onError
)
}
private fun attachSearchMoviesOnScrollListener() {
searchMovies.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = searchMoviesLayoutMgr.itemCount
val visibleItemCount = searchMoviesLayoutMgr.childCount
val firstVisibleItem = searchMoviesLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
searchMovies.removeOnScrollListener(this)
searchMoviesPage++
getSearchMovies()
}
}
})
}
private fun onSearchMoviesFetched(movies: List<Movie>) {
searchMoviesAdapter.appendMovies(movies)
attachSearchMoviesOnScrollListener()
}
private fun getPopularTV() {
TVRepository.getSearchTV(
searchTVPage,
searchKeyword,
::onSearchTVFetched,
::onError
)
}
private fun onSearchTVFetched(tvlist: List<TV>) {
searchTVAdapter.appendTV(tvlist)
attachSearchTVOnScrollListener()
}
private fun attachSearchTVOnScrollListener() {
searchTV.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val totalItemCount = searchTVLayoutMgr.itemCount
val visibleItemCount = searchTVLayoutMgr.childCount
val firstVisibleItem = searchTVLayoutMgr.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
searchTV.removeOnScrollListener(this)
searchTVPage++
getPopularTV()
}
}
})
}
private fun onError() {
Toast.makeText(activity, "error error", Toast.LENGTH_SHORT).show()
}
private fun showMovieDetails(movie: Movie) {
val intent = Intent(activity, MovieDetailsActivity::class.java)
intent.putExtra(MainActivity.MOVIE_BACKDROP, movie.backdrop_path)
intent.putExtra(MainActivity.MOVIE_POSTER, movie.poster_path)
intent.putExtra(MainActivity.MOVIE_TITLE, movie.title)
intent.putExtra(MainActivity.MOVIE_RATING, movie.rating)
intent.putExtra(MainActivity.MOVIE_RELEASE_DATE, movie.releaseDate)
intent.putExtra(MainActivity.MOVIE_OVERVIEW, movie.overview)
startActivity(intent)
}
private fun showTVDetails(tv: TV) {
val intent = Intent(activity, MovieDetailsActivity::class.java)
intent.putExtra(MainActivity.MOVIE_BACKDROP, tv.backdrop_path)
intent.putExtra(MainActivity.MOVIE_POSTER, tv.poster_path)
intent.putExtra(MainActivity.MOVIE_TITLE, tv.name)
intent.putExtra(MainActivity.MOVIE_RATING, tv.rating)
intent.putExtra(MainActivity.MOVIE_RELEASE_DATE, tv.first_air_date)
intent.putExtra(MainActivity.MOVIE_OVERVIEW, tv.overview)
startActivity(intent)
}
}
package com.example.moving.ui.notifications
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class NotificationsViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is notifications Fragment"
}
val text: LiveData<String> = _text
}
비동기 프로그래밍은 주요 작업 흐름을 차단하지 않고 별도의 작업 흐름에서 태스크를 실행하는 프로그래밍 방식입니다. 주요 작업(예: UI 스레드)을 차단하지 않고 복잡하거나 시간이 오래 걸리는 작업을 처리하기 위해 사용됩니다. 이를 통해 애플리케이션의 반응성이 향상됩니다.
RESTful API와의 통신은 주로 HTTP 프로토콜을 사용하여 이루어집니다. 안드로이드에서는 Retrofit, OkHttp와 같은 라이브러리를 사용하여 API 호출을 수행합니다.
명시적 인텐트는 인텐트에 클래스 객체나 컴포넌트 이름을 지정하여 호출할 대상을 확실히 알 수 있는 경우에 사용합니다. 주로 애플리케이션 내부에서 사용합니다. 인텐트의 액션과 데이터를 지정하긴 했지만, 호출할 대상이 달라질 수 있는 경우에는 암시적 인텐트를 사용합니다.
즉 설치된 애플리케이션들에 대한 정보를 알고 있는 안드로이드 시스템이 인텐트를 이용해 요청한 정보를 처리할 수 있는 적절한 콤포넌트를 찾아본 다음 사용자에게 그 대상과 처리 결과를 보여주는 과정을 거치게 됩니다.
백그라운드 서비스와 포그라운드 서비스의 가장 큰 차이점은, 사용자가 서비스의 존재에 대해 인지할 수 있는지 없는지에 대한 차이라고 볼 수 있다.
딥링크는 인텐트필터의 일종으로 사용자들이 직접적으로 안드로이드 앱내의 액티비티에 접근하는것을 허용합니다. 다른 앱에서 또는 웹브라우저에서의 링크를 클릭했을때 해당 링크의 scheme을 보고 앱을 실행하게 되며, 해당 링크를 처리하는 2개이상의 앱이 있다면 사용자에게 다이얼로그를 띄어 앱을 실행할 수 있도록 유도 합니다. 앱링크는 인증된 웹사이트 URL을 기반으로 하는 딥링크입니다. 링크 클릭시 앱이 설치되어있다면 즉시 열어서 보여주고 없다면 웹으로 이동합니다. 다이얼로그는 나타나지 않습니다.
BroadCastReceiver 의 역할은 단말기 안에서 이루어지는 수많은 일들을 대신해서 알려준다. 예를들어 배터리부족,SMS문자메시지,전화가온다거나 하는 일들을 방송알림 해준다.
디자인 패턴 = 검증된 소프트웨어 개발 설계 방법이다. 안드로이드 앱을 설계할 때 디자인 패턴을 적용. 이미 검증된 패턴이므로 문제가 발생할 일이 적다. 정형화된 패턴이므로 개발자 간의 의사소통이 수월해진다. 더 유연하고 좋은 코드를 사용할 수 있다. 디자인 패턴은 크게 3종류로 나뉜다. 생성 패턴, 구조 패턴, 행위 패턴
보완대체 의사소통 시스템(AAC)는 많은 장애인들의 의사소통 및 언어의 어려움을 보완하거나 대체하는 것을 목표로 하는 구어와는 다른 표현 방식입니다.
앱에는 특정 문화에 관련된 리소스가 포함됩니다. 예를 들어, 앱에는 현재 설정된 언어로 번역되는 문화 관련 문자열이 포함될 수 있습니다. 문화 관련 리소스는 앱의 다른 부분과 분리하는 것이 좋습니다. Android는 시스템 언어 설정에 따라 언어 및 문화 관련 리소스를 결정합니다. Android 프로젝트의 리소스 디렉터리를 사용하여 다양한 언어를 지원할 수 있습니다.
BroadCastReceiver 의 역할은 단말기 안에서 이루어지는 수많은 일들을 대신해서 알려준다. 예를들어 배터리부족,SMS문자메시지,전화가온다거나 하는 일들을 방송알림 해준다.