Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#8 [ui] Daily Routine - 추가하기 #18

Merged
merged 45 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
30917a4
[add] : drawable 및 이미지 에셋 추출
minemi00 Jan 9, 2024
411796f
[feat] 데일리 루틴 테마 리사이클러뷰 item
minemi00 Jan 9, 2024
9272708
[add] 인디케이터 selector 만들기
minemi00 Jan 9, 2024
13db25d
[ui] 데일리 루틴 추가하기 1차 구현
minemi00 Jan 9, 2024
d3b843a
[add] 데일리루틴 뷰페이저 어댑터 생성
minemi00 Jan 9, 2024
c5c057f
[feat] 데일리루틴 추가 viewpager, indicator 로직
minemi00 Jan 9, 2024
022f0a8
[feat] 데일리루틴 추가 viewpager, indicator 로직
minemi00 Jan 9, 2024
b81bf10
[chore] indicator 수정
minemi00 Jan 9, 2024
041f285
[feat] 리사이클러뷰 연결
minemi00 Jan 9, 2024
fdecc78
[chore] 이미지 로드 이슈 해결
minemi00 Jan 9, 2024
a859f4e
[chore] 뷰페이저 가운데 정렬 완
minemi00 Jan 9, 2024
6ec660e
[chore] 뷰페이저 가운데 정렬 완
minemi00 Jan 9, 2024
db96226
[add] manifest에 데일리루틴추가하기 뷰 추가
minemi00 Jan 10, 2024
bf52dfe
[chore] 글자 행간 수정
minemi00 Jan 10, 2024
47d5fdf
[chore] 리사이클러뷰 클릭이벤트 수정
minemi00 Jan 10, 2024
5527708
Merge branch 'develop' of https://github.com/Team-Sopetit/Sopetit-And…
minemi00 Jan 11, 2024
b6ca29f
[chore] 네이밍 및 폴더링 변경
minemi00 Jan 11, 2024
66e7e17
[chore] mocklist, 데이터클래스 변경
minemi00 Jan 11, 2024
82afb19
Merge branch 'develop' of https://github.com/Team-Sopetit/Sopetit-And…
minemi00 Jan 11, 2024
ccb3045
#8 [chore] 뷰모델 가짜데이터, 데이터 클래스 수정
minemi00 Jan 11, 2024
3b8a9f9
#8 [chore] 뷰페이저 양옆 보이게 수정
minemi00 Jan 11, 2024
249f79d
Merge branch 'develop' of https://github.com/Team-Sopetit/Sopetit-And…
minemi00 Jan 11, 2024
9f2ea54
#8 [chore] 이미지 로드 이슈 해결
minemi00 Jan 12, 2024
63d2a52
#8 [feat] 리사이클러뷰 클릭 이벤트 적용
minemi00 Jan 12, 2024
14c3e99
#8 [feat] : 리사이클러뷰 클릭이벤트 색깔 바뀌게
minemi00 Jan 12, 2024
2d71560
#8 [chore] : 이미지 로드 문제 해결
minemi00 Jan 12, 2024
7b7fd6d
#8 [chore] : 이미지 로드 비율 맞추기
minemi00 Jan 12, 2024
7432bc5
Merge branch 'develop' of https://github.com/Team-Sopetit/Sopetit-And…
minemi00 Jan 12, 2024
4a4db0f
#8 [chore] : 이미지 로드 비율 수정
minemi00 Jan 12, 2024
d51808e
#8 [chore] : ci 오류 수정
minemi00 Jan 12, 2024
85e1ad0
#8 [chore] : ci 오류 재수정
minemi00 Jan 12, 2024
ce2ab8b
#8 [chore] : ci 오류 재수정
minemi00 Jan 12, 2024
f3f751c
#8 [chore] : ci 오류 재수정
minemi00 Jan 12, 2024
c490a1a
#8 [chore] : 테마 리스트 변수명 변경
minemi00 Jan 12, 2024
f0d7e14
#8 [refact] : 코드리뷰 반영
minemi00 Jan 14, 2024
fe5d383
#8 [add] : 데일리추가하기 데이터 클래스 생성
minemi00 Jan 14, 2024
0182c04
#8 [refact] : 데일리 루틴 리스트 불러오기
minemi00 Jan 14, 2024
f608e2d
Merge branch 'develop' of https://github.com/Team-Sopetit/Sopetit-And…
minemi00 Jan 14, 2024
914c300
#8 [chore] : ci 오류 수정
minemi00 Jan 14, 2024
7d53ab7
#8 [add] : 액티비티 종료
minemi00 Jan 14, 2024
1ce1e29
#8 [add] : 액티비티 종료
minemi00 Jan 14, 2024
8e73d6c
Merge branch 'develop' of https://github.com/Team-Sopetit/Sopetit-And…
minemi00 Jan 14, 2024
2ba41c2
#8 [chore] : 중복 indicator 삭제
minemi00 Jan 14, 2024
a3713b0
#8 [chore] : 코드리뷰 반영
minemi00 Jan 14, 2024
dea9844
#8 [add] : 데일리루틴뷰, 추가뷰 연결
minemi00 Jan 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ dependencies {
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

// indicator
implementation("com.tbuonomo:dotsindicator:5.0")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 삭제해주세요~

}

fun getApiKey(propertyKey: String): String {
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
</intent-filter>
</activity>

<activity
android:name=".ui.dailyroutine.dailyroutineadd.DailyRoutineAddActivity"
android:exported="false"
android:screenOrientation="portrait" />

<activity
android:name=".ui.happyroutine.addlist.HappyAddListActivity"
android:exported="false"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.sopetit.softie.domain.entity

data class DailyCard(
val backgroundImageUrl: String,
val routineId: Int,
val content: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.sopetit.softie.domain.entity

data class DailyRoutineAdd(
val themeId: Int,
val dailyRoutineCardList: List<DailyCard>
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ data class Theme(
val themeId: Int,
val name: String,
val iconImageUrl: String,
val backgroudnImageUrl: String
val backgroundImageUrl: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package com.sopetit.softie.ui.dailyroutine.dailyroutineadd

import android.graphics.Rect
import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.CompositePageTransformer
import androidx.viewpager2.widget.MarginPageTransformer
import androidx.viewpager2.widget.ViewPager2
import com.sopetit.softie.R
import com.sopetit.softie.databinding.ActivityDailyRoutineAddBinding
import com.sopetit.softie.domain.entity.Theme
import com.sopetit.softie.util.binding.BindingActivity

class DailyRoutineAddActivity :
BindingActivity<ActivityDailyRoutineAddBinding>(R.layout.activity_daily_routine_add) {
private lateinit var viewPager: ViewPager2
private lateinit var dailyRoutineAddCardPagerAdapter: DailyRoutineAddCardPagerAdapter
private lateinit var dailyRoutineAddThemeAdapter: DailyRoutineAddThemeAdapter

private val dailyRoutineAddViewModel by viewModels<DailyRoutineAddViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewPager = binding.vpDailyRoutineAddCard
binding.viewModel = dailyRoutineAddViewModel

setupAdapter()
setViewPager()
setupList()
setIndicator()
setItemDiv()
initPagerDiv(0, 90)
addRoutine()
}

private fun setupAdapter() {
with(binding) {
dailyRoutineAddCardPagerAdapter = DailyRoutineAddCardPagerAdapter()
vpDailyRoutineAddCard.adapter = dailyRoutineAddCardPagerAdapter
dailyRoutineAddThemeAdapter = DailyRoutineAddThemeAdapter().apply {
setOnItemClickListener(object : DailyRoutineAddThemeAdapter.OnItemClickListener {
override fun onItemClick(item: Theme, position: Int) {
setRoutineList(item.themeId)
}
})
}
rvDailyRoutineAddTheme.adapter = dailyRoutineAddThemeAdapter
}
}

private fun setupList() {
dailyRoutineAddViewModel.mockThemeList.observe(this) {
dailyRoutineAddCardPagerAdapter.submitList(dailyRoutineAddViewModel.startNewDayCardList.value)
dailyRoutineAddThemeAdapter.submitList(dailyRoutineAddViewModel.mockThemeList.value)
}
}

private fun setRoutineList(themeId: Int) {
dailyRoutineAddCardPagerAdapter.submitList(
dailyRoutineAddViewModel.getDailyCardListForId(themeId)[0].dailyRoutineCardList
)
}

private fun initPagerDiv(previewWidth: Int, itemMargin: Int) {
val decoMargin = previewWidth + itemMargin
val pageTransX = decoMargin + previewWidth
val decoration = PageDecoration(decoMargin)

binding.vpDailyRoutineAddCard.also {
it.offscreenPageLimit = VIEW_PAGE.toInt()
it.addItemDecoration(decoration)
it.setPageTransformer { page, position ->
page.translationX = position * -pageTransX
}
}
}

private fun setViewPager() {
with(binding.vpDailyRoutineAddCard) {
adapter = dailyRoutineAddCardPagerAdapter
offscreenPageLimit = VIEW_PAGE.toInt()

val dpValue = PADDING_PAGE
val margin = (dpValue * resources.displayMetrics.density).toInt()
setPadding(margin, PADDING_CARD, margin, PADDING_CARD)

setPageTransformer(
CompositePageTransformer().apply {
addTransformer(
MarginPageTransformer(
resources.getDimensionPixelOffset(R.dimen.viewpager_margin)
)
)
}
)
}
}

private fun setIndicator() {
binding.diDailyRoutineAddIndicator.attachTo(binding.vpDailyRoutineAddCard)
}

private class PageDecoration(private val margin: Int) : RecyclerView.ItemDecoration() {

override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
outRect.left = margin
outRect.right = margin
}
}

class HorizontalItemDecorator(private val divHeight: Int) : RecyclerView.ItemDecoration() {
@Override
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
outRect.left = divHeight
outRect.right = divHeight
}
}

private fun setItemDiv() {
binding.rvDailyRoutineAddTheme.addItemDecoration(HorizontalItemDecorator(16))
}

private fun addRoutine() {
binding.btnDailyRoutineAdd.setOnClickListener {
finish()
}
}

companion object {
const val VIEW_PAGE = 3
const val PADDING_PAGE = 40
const val PADDING_CARD = 0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.sopetit.softie.ui.dailyroutine.dailyroutineadd

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.sopetit.softie.databinding.ItemDailyRoutineAddCardBinding
import com.sopetit.softie.domain.entity.DailyCard
import com.sopetit.softie.util.ItemDiffCallback
import timber.log.Timber

class DailyRoutineAddCardPagerAdapter :
ListAdapter<DailyCard, DailyRoutineAddCardPagerAdapter.DailyPagerViewHolder>(
ItemDiffCallback<DailyCard>(
onItemsTheSame = { oldItem, newItem -> oldItem == newItem },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분에 item이 고유한 값으로 지닌 값으로 비교해주세요~
예시로,

Suggested change
onItemsTheSame = { oldItem, newItem -> oldItem == newItem },
onItemsTheSame = { oldItem, newItem -> oldItem.themeId == newItem.themeId },

onContentsTheSame = { oldItem, newItem -> oldItem == newItem }
)
) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DailyPagerViewHolder {
val binding = ItemDailyRoutineAddCardBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return DailyPagerViewHolder(binding)
}

override fun onBindViewHolder(holder: DailyPagerViewHolder, position: Int) {
holder.onBind(currentList[position])
}

class DailyPagerViewHolder(private val binding: ItemDailyRoutineAddCardBinding) :
RecyclerView.ViewHolder(binding.root) {
fun onBind(data: DailyCard) {
binding.tvDailyRoutineAddCard.load(data.backgroundImageUrl)
Timber.d("load Image -> $data")
binding.tvDailyRoutineAddCardName.text = data.content
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.sopetit.softie.ui.dailyroutine.dailyroutineadd

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.sopetit.softie.R
import com.sopetit.softie.databinding.ItemDailyRoutineAddThemeBinding
import com.sopetit.softie.domain.entity.Theme
import com.sopetit.softie.util.ItemDiffCallback

class DailyRoutineAddThemeAdapter :
ListAdapter<Theme, DailyRoutineAddThemeAdapter.DailyThemeViewHolder>(
ItemDiffCallback<Theme>(
onItemsTheSame = { old, new -> old.themeId == new.themeId },
onContentsTheSame = { old, new -> old == new }
)
) {
private var onItemClickListener: OnItemClickListener? = null
private var selectedPosition = 0
var clickedThemeId: Int = 1

interface OnItemClickListener {
fun onItemClick(item: Theme, position: Int)
}

fun setOnItemClickListener(listener: OnItemClickListener) {
this.onItemClickListener = listener
}

inner class DailyThemeViewHolder(
private val binding: ItemDailyRoutineAddThemeBinding
) :
RecyclerView.ViewHolder(binding.root) {
fun onBind(data: Theme) {
binding.tvDailyRoutineAddThemeName.text = data.name
binding.ivDailyRoutineAddThemeIcon.load(data.iconImageUrl)
if (selectedPosition == absoluteAdapterPosition) {
changeThemeBackground(binding, true)
changeThemeTextColor(binding, true)
} else {
changeThemeBackground(binding, false)
changeThemeTextColor(binding, false)
}

if (onItemClickListener != null) {
binding.root.setOnClickListener {
onItemClickListener?.onItemClick(data, absoluteAdapterPosition)
if (selectedPosition != absoluteAdapterPosition) {
changeThemeBackground(binding, true)
changeThemeTextColor(binding, true)
notifyItemChanged(selectedPosition)
selectedPosition = absoluteAdapterPosition
}
clickedThemeId = data.themeId
}
}
}
}

private fun changeThemeBackground(
binding: ItemDailyRoutineAddThemeBinding,
selected: Boolean
) {
when (selected) {
true -> {
binding.ivDailyRoutineAddThemeBackground.setBackgroundResource(R.drawable.ic_daily_theme_background_click)
}

false -> {
binding.ivDailyRoutineAddThemeBackground.setBackgroundResource(R.drawable.ic_daily_theme_background)
}
}
}

private fun changeThemeTextColor(
binding: ItemDailyRoutineAddThemeBinding,
selected: Boolean
) {
when (selected) {
true -> {
binding.tvDailyRoutineAddThemeName.setTextColor(
ContextCompat.getColor(
binding.root.context,
R.color.gray700
)
)
}

false -> {
binding.tvDailyRoutineAddThemeName.setTextColor(
ContextCompat.getColor(
binding.root.context,
R.color.gray400
)
)
}
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DailyThemeViewHolder {
val binding = ItemDailyRoutineAddThemeBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return DailyThemeViewHolder(binding)
}

override fun onBindViewHolder(holder: DailyThemeViewHolder, position: Int) {
holder.onBind(currentList[position])
}
}
Loading