인턴 경험이 중요시 되는 요즘!
많은 대학생들은 여기 저기에서 인턴 공고를 찾아다니고 정보를 얻기 위해 발버둥을 치고 있습니다.
저희 인턴즈는 인턴을 준비하는 과정 속에서 발생하는 대학생들의 고민을 해결하기 위해 맞춤 인턴 정보 추천 , 캘린더를 통한 인턴 공고 관리 , 프로필 타임라인과 스토리를 통한 경험 공유 및 소통 을 위한 서비스를 제공하고 있습니다.
인턴 경험의 시작부터 마무리까지! 인턴즈와 함께하세요~
2019.12.23 - 2020.01.04
-
view pager , tablayout
implementation 'com.android.support:design:29.1.0'
홈 화면 중앙에 있는 맞춤 공고와 onBoarding을 구현하기 위해 사용
-
glide
implementation 'com.github.bumptech.glide:glide:4.10.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
프로필 원형 이미지 및 공고 이미지를 보여주기 위해 사용
-
retrofit, Gson
implementation 'com.squareup.retrofit2:retrofit:2.6.2' implementation 'com.squareup.retrofit2:retrofit-mock:2.6.2' implementation 'com.squareup.retrofit2:converter-gson:2.6.2' implementation 'com.google.code.gson:gson:2.8.6'
서버 통신을 위해 사용
-
recyclerview
implementation 'androidx.recyclerview:recyclerview:1.1.0'
반복되는 아이템들을 효과적으로 구현하기 위해 사용
-
calendar
implementation 'com.prolificinteractive:material-calendarview:1.4.3'
커스텀 달력을 구현하기 위해 사용
-
circle Indicator
implementation 'me.relex:circleindicator:1.2.2'
viewPager의 indicator 변경을 위해 사용
-
swipe menu Layout
implementation 'com.github.anzaizai:EasySwipeMenuLayout:1.1.4'
스와이프 하여 공고 추가를 위해 사용
-
swipe for refresh
implementation 'androidx.appcompat:appcompat:1.0.0'
당겨서 새로고침 하기위해 사용
-
snapHelper
implementation 'com.github.rubensousa:gravitysnaphelper:2.2.0'
보다 더 자연스러운 스와이프 효과를 구현하기 위해 사용
-
권한 허용
implementation 'gun0912.ted:tedpermission:2.1.0'
디바이스에서 사진을 가져오기 위해 사용
Activity | 설명 |
---|---|
SplashAcitivity |
앱 실행시 첫 화면 |
SigninAcitivity |
로그인 성공 시 MainActivity로 이동 첫 로그인 시 JobSelectAcitivity로 이동 회원가입 시 SignUpAcitivity로 이동 |
SignupAcitivity |
이메일, 비밀번호, 핸드폰 번호, 닉네임, 성별, 약관동의 |
JobSelectAcitivity |
무 선택 후 프로필 사진과 한줄 소개 작성 |
BottomBarActivity |
홈, 공고, 스토리, 프로필 하단 탭 |
HomeFragment |
맞춤 공고, 추천 프로필, 오늘의 스토리 |
NotificationFragment |
인턴 공고 리스트(최신순, 조회순) |
StoryActivity |
스토리 리스트(최신순, 조회순) |
ProfileActivity |
개인 프로필 정보 개인 프로필 정보 타임라인 리스트 |
CommentAcitivity |
댓글을 주고 받을 수 있는 화면 |
followerActivity |
팔로워 리스트 확인할 수 있는 화면 |
followingActivity |
팔로잉 리스트 확인 |
DetailStoryAcitivity |
상세 스토리 확인 |
CalendarActivity |
달력에 공고 일정 추가 및 확인 |
MessageActivity |
쪽지를 주고 받을 수 있는 화면 |
filterActivity |
공고 필터를 선택할 수 있는 화면 |
onboardingActivity |
어플 처음 실행시 어플을 소개하는 화면 |
WebViewActivity |
공고 클릭시 링크로 이동하는 화면 |
Package | 설명 |
---|---|
api |
서버 통신을 위한 패키지 |
common |
Extension function을 위한 패키지 |
data |
data 관리를 위한 패키지 |
feature |
보조 기능을 구분하기 위한 패키지 |
ui |
주요 기능을 구분하기 위한 패키지 |
-
Custom Calendar Implemetation
Material 디자인 기반으로 한 달력 라이브러리를 사용하여 캘린더 UI를 구현.
월별 일자 와 해당 월의 전체 공고 일자를 비교하여 일치하는 날짜에 표시
-
Bottom Navigation Bar
하단의 탭 아이템과 각 프래그먼트를 연결
hide(), show() 메서드를 사용하여 각 프래그먼트의 상태 유지
-
필터에 따른 공고 확인 기능
필터를 적용하여 27가지 이상의 맞춤형 공고 리스트 확인 가능
-
팔로잉 팔로우 기능
상호간의 팔로잉, 팔로우가 가능하며 팔로우, 팔로잉된 리스트를 볼 수 있음
-
스토리 주제 세분화
다양한 주제의 스토리 작성 및 확인 가능
-
쪽지 기능
상호간의 쪽지 보내기 및 받기 가능
- Body에 data가 없는 경우 사용한 Extension function
data class CallWithoutDataExt(
val message: String,
val status: Int,
val success: Boolean
)
fun Call<CallWithoutDataExt>.enqueue(
onError: (Throwable) -> Unit = onStandardError,
onSuccess: (CallWithoutDataExt) -> Unit = {},
onFail: (status: Int, message: String) -> Unit = {_, _ -> Unit}
) {
this.enqueue(object : Callback<CallWithoutDataExt> {
override fun onFailure(call: Call<CallWithoutDataExt>, t: Throwable) {
onError(t)
}
override fun onResponse(call: Call<CallWithoutDataExt>, response: Response<CallWithoutDataExt>) {
if (response.isSuccessful) {
response.body()?.let {
onSuccess(it)
} ?: onFail(response.body()?.status?:-1, response.body()?.message.orEmpty())
} else {
onFail(response.body()?.status?:-1, response.body()?.message.orEmpty())
}
}
})
}
private val onStandardError: (Throwable) -> Unit = {
Log.e("CallExt", "network error $it")
}
- Body에 data가 있을 경우 사용한 Extension function
data class BaseResponse<T>(
val message: String,
val status: Int,
val success: Boolean,
val data: T?
)
fun <T> Call<BaseResponse<T>>.enqueue(
onError: (Throwable) -> Unit = onStandardError,
onSuccess: (T) -> Unit = {},
onFail: (status: Int, message: String) -> Unit = {_, _ -> Unit}
) {
this.enqueue(object : Callback<BaseResponse<T>> {
override fun onFailure(call: Call<BaseResponse<T>>, t: Throwable) {
onError(t)
}
override fun onResponse(call: Call<BaseResponse<T>>, response: Response<BaseResponse<T>>) {
if (response.isSuccessful) {
response.body()?.data?.let {
onSuccess(it)
} ?: onFail(response.body()?.status?:-1, response.body()?.message.orEmpty())
} else {
onFail(response.body()?.status?:-1, response.body()?.message.orEmpty())
}
}
})
}
private val onStandardError: (Throwable) -> Unit = {
Log.e("CallExt", "network error $it")
}
코드의 반복을 줄이기 위해 call 함수를 extenstion 함
서버에서 받는 body에 기본적으로 포함된 status, message, success가 아닌 추가로 data가 있을 경우를 대비하여 data가 추가된 확장 함수를 만듦
- 코드를 간결하게 하기 위해 람다 표현식 사용
onError: (Throwable) -> Unit = onStandardError,
onSuccess: (CallWithoutDataExt) -> Unit = {},
onFail: (status: Int, message: String) -> Unit = {_, _ -> Unit}
followingNum.setOnClickListener {
val intent = Intent(this@MainProfileFragment.context , FollowingListActivity::class.java)
startActivity(intent)
}
- onBoardingActivity
<?xml version="1.0" encoding="utf-8"?>
<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"
>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:tabMode="fixed"
app:tabIndicatorColor="#ffffff"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<me.relex.circleindicator.CircleIndicator
android:id="@+id/onBoardingIndicator"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="80dp"
app:ci_drawable="@drawable/yellow_radius"
app:ci_drawable_unselected="@drawable/black_radius"
app:ci_height="5dp"
app:ci_width="5dp"
app:ci_margin="4dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager2"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>