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

refactor: BindingAdapter 분리 및 리팩토링 #469 #472

Merged
merged 13 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.on.staccato.presentation.bindingadapter

import android.widget.Button
import android.widget.ImageButton
import androidx.databinding.BindingAdapter
import com.google.android.material.button.MaterialButton
import com.on.staccato.R
import com.on.staccato.domain.model.MemoryCandidate
import com.on.staccato.presentation.momentcreation.model.AttachedPhotosUiModel
import java.time.LocalDate
import java.time.LocalDateTime

@BindingAdapter("loginButtonEnabled")
fun Button.setLoginButtonEnabled(nickName: String?) {
isEnabled =
if (nickName.isNullOrBlank()) {
setTextColor(resources.getColor(R.color.gray4, null))
false
} else {
setTextColor(resources.getColor(R.color.white, null))
true
}
}

@BindingAdapter(
value = ["staccatoTitle", "staccatoAddress", "staccatoVisitedAt", "staccatoPhotos", "staccatoMemory"],
)
fun Button.setStaccatoSaveButtonEnabled(
staccatoTitle: String?,
staccatoAddress: String?,
staccatoVisitedAt: LocalDateTime?,
staccatoPhotos: AttachedPhotosUiModel?,
staccatoMemory: MemoryCandidate?,
) {
isEnabled =
if (staccatoTitle.isNullOrBlank() ||
staccatoAddress == null ||
staccatoMemory == null ||
staccatoVisitedAt == null ||
staccatoPhotos?.isLoading() == true
) {
setTextColor(resources.getColor(R.color.gray4, null))
false
} else {
setTextColor(resources.getColor(R.color.white, null))
true
}
}

@BindingAdapter(
value = ["memoryTitle", "memoryStartDate", "memoryEndDate", "isPeriodActive", "isPhotoUploading"],
)
fun Button.setMemorySaveButtonEnabled(
memoryTitle: String?,
memoryStartDate: LocalDate?,
memoryEndDate: LocalDate?,
isPeriodActive: Boolean,
isPhotoUploading: Boolean?,
) {
val isPeriodNotExistent = (memoryStartDate == null) || (memoryEndDate == null)
val isPeriodRequirementsInvalid = isPeriodActive && isPeriodNotExistent
isEnabled =
if (memoryTitle.isNullOrBlank() || isPhotoUploading == true || isPeriodRequirementsInvalid) {
setTextColor(resources.getColor(R.color.gray4, null))
false
} else {
setTextColor(resources.getColor(R.color.white, null))
true
}
}

@BindingAdapter("visitedAtSelectButtonEnabled")
fun Button.setVisitedAtSelectButtonEnabled(years: List<Int>?) {
isEnabled =
if (years.isNullOrEmpty()) {
setTextColor(resources.getColor(R.color.gray4, null))
false
} else {
setTextColor(resources.getColor(R.color.white, null))
true
}
}

@BindingAdapter("recoveryButtonEnabled")
fun Button.setRecoveryButtonEnabled(recoveryCode: String?) {
isEnabled =
if (recoveryCode.isNullOrBlank() || recoveryCode.length < 36) {
Copy link
Contributor

Choose a reason for hiding this comment

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

36도 상수화하면 좋을 것 같아요~

setTextColor(resources.getColor(R.color.gray4, null))
false
} else {
setTextColor(resources.getColor(R.color.white, null))
true
}
}

@BindingAdapter("currentLocationButtonLoading")
fun MaterialButton.setCurrentLocationButtonLoading(isLoading: Boolean?) {
isClickable = isLoading == false
if (isLoading == true) {
setText(R.string.all_empty)
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
} else {
setText(R.string.visit_creation_load_current_location)
}
}

@BindingAdapter("sendButtonEnabled")
fun ImageButton.setSendButtonEnabled(value: String?) {
isEnabled = !value.isNullOrBlank()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

파일 이름에 오타가 있는 것 같아요..!! Etc~

Copy link
Contributor Author

@s6m1n s6m1n Oct 14, 2024

Choose a reason for hiding this comment

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

뷰 종류에 상관 없는 메서드들을 담은 파일은 BindingAdapters.kt로 수정했습니다!

Copy link
Contributor

Choose a reason for hiding this comment

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

Etc 를 Etx 로 오타를 내신 것 같네요! 😂
분리를 하고 나머지 뷰들의 바인딩 어댑터임을 명시하기 위해 파일 이름을 이와 같이 변경하신 것 같은데,
저는 기존의 BindingAdapters.kt 가 좋아보여요!

기존에 존재하던 BindingAdapters 에서 너무 많은 메서드를 가진 View의 경우만 분리를 해주신 것이니,
"남은 자잘한 뷰들의 바인딩 어댑터에요~" 하고 파일 이름에 나타낼 이유는 크게 없어보였어요!

그리고 빙티가 파일 분리를 하면서 어떤 View의 바인딩 어댑터인지 파일 이름에 잘 명시해주셨어요.
그래서 이를 활용할 동료 개발자의 입장에서도 혼란이 일어날 것 같지 않아요~

Copy link
Contributor Author

Choose a reason for hiding this comment

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

반영했습니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.on.staccato.presentation.bindingadapter

import android.net.Uri
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.ScrollView
import androidx.databinding.BindingAdapter
import com.on.staccato.presentation.timeline.model.TimelineUiModel

@BindingAdapter("visibleOrGone")
fun View.setVisibility(isVisible: Boolean?) {
visibility =
if (isVisible == true) {
View.VISIBLE
} else {
View.GONE
}
}

@BindingAdapter("scrollableToBottom")
fun ScrollView.isScrollableToBottom(isScrollable: Boolean) {
Copy link
Contributor

Choose a reason for hiding this comment

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

다른 화면의 스크롤 뷰에도 적용할 수 있도록 메서드와 파라미터 이름을 변경하신 것 같네요!

메서드의 파라미터로 들어온 Boolean 값이 true 인 경우, 스크롤을 맨 하단으로 강제 이동

해당 바인딩어댑터는 위와 같이 조건에 의해 수행되고 강제성을 띄기 때문에, 가능성을 나타내는 scrollable 이라는 이름이 들어간 것이 어색하게 느껴졌어요.
비슷한 예로 View의 가시성을 설정하는 바인딩어댑터의 메서드 명은 가능성을 나타내고있지 않죠!

@BindingAdapter("visibleOrGone")
fun View.setVisibility(isVisible: Boolean?)

바인딩 어댑터 메서드 명의 통일성을 유지하고,
값이 true인 경우 맨 아래로 스크롤한다 라는 동작이 잘 나타나도록 아래와 같은 예시를 참고해보는 것은 어떨까요?

Suggested change
@BindingAdapter("scrollableToBottom")
fun ScrollView.isScrollableToBottom(isScrollable: Boolean) {
@BindingAdapter("scrollToBottom")
fun ScrollView.setScrollToBottom(isActive: Boolean) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

좋은 의견 감사합니다! 확실히 scrollable이란 표현은 어색하네요..ㅎㅎ 반영하였습니다

다만, 파라미터로 들어온 Boolean 값에 따라 스크롤을 맨 하단으로 강제 이동하는 메서드이므로
파라미터 명은 isScrollable: Boolean 가 더 자연스럽다고 생각해 기존처럼 유지했습니다~!~!

if (isScrollable) {
post { fullScroll(ScrollView.FOCUS_DOWN) }
}
}

@BindingAdapter(value = ["visibilityByThumbnailUri", "visibilityByThumbnailUrl"])
fun View.setThumbnail(
thumbnailUri: Uri?,
thumbnailUrl: String?,
) {
visibility =
if (thumbnailUri == null && thumbnailUrl == null) {
View.VISIBLE
} else {
View.GONE
}
}

@BindingAdapter(value = ["visibilityByThumbnailUri", "visibilityByThumbnailUrl"])
fun ProgressBar.setThumbnailLoadingProgressBar(
thumbnailUri: Uri?,
thumbnailUrl: String?,
) {
visibility =
if (thumbnailUri != null && thumbnailUrl == null) {
View.VISIBLE
} else {
View.GONE
}
}

@BindingAdapter(
value = ["visibilityByTimeline", "visibilityByLoading"],
)
fun View.setTimelineEmptyViewVisible(
timeLine: List<TimelineUiModel>? = null,
isTimelineLoading: Boolean,
) {
visibility = if (isTimeLineEmpty(timeLine, isTimelineLoading)) View.VISIBLE else View.GONE
}

@BindingAdapter(
value = ["visibilityByTimeline", "visibilityByLoading"],
)
fun ViewGroup.setMemoryAddButtonVisible(
timeLine: List<TimelineUiModel>? = null,
isTimelineLoading: Boolean,
) {
visibility = if (isTimeLineEmpty(timeLine, isTimelineLoading)) View.GONE else View.VISIBLE
}

private fun isTimeLineEmpty(
timeLine: List<TimelineUiModel>?,
isTimelineLoading: Boolean,
) = timeLine.isNullOrEmpty() && isTimelineLoading.not()
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.on.staccato.presentation.bindingadapter

import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import coil.load
import coil.transform.RoundedCornersTransformation

@BindingAdapter("selected")
fun ImageView.setSelected(selected: Boolean) {
isSelected = selected
}

@BindingAdapter(
value = ["coilImageUrl", "coilPlaceHolder"],
)
fun ImageView.loadCoilImage(
url: String?,
placeHolder: Drawable? = null,
) {
load(url) {
placeholder(placeHolder)
error(placeHolder)
}
}

@BindingAdapter(
value = ["coilImageUri", "coilPlaceHolder"],
)
fun ImageView.loadCoilImageByUri(
uri: Uri?,
placeHolder: Drawable? = null,
) {
load(uri) {
placeholder(placeHolder)
error(placeHolder)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

해당 BindingAdapter는 사용되고 있지 않는데 제거해도 되지 않을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

제거했습니다!


@BindingAdapter(
value = ["coilCircleImageUrl", "coilPlaceHolder"],
)
fun ImageView.loadCoilCircleImage(
url: String?,
placeHolder: Drawable? = null,
) {
load(url) {
placeholder(placeHolder)
transformations(RoundedCornersTransformation(1000f))
error(placeHolder)
}
}

@BindingAdapter(
value = ["coilRoundedCornerImageUrl", "coilRoundedCornerPlaceHolder", "coilRoundingRadius"],
)
fun ImageView.setCoilRoundedCornerImage(
url: String?,
placeHolder: Drawable? = null,
roundingRadius: Float,
) {
load(url) {
placeholder(placeHolder)
transformations(RoundedCornersTransformation(roundingRadius))
error(placeHolder)
}
}

@BindingAdapter(
value = ["coilRoundedCornerImageUrl", "coilRoundedCornerImageUri", "coilRoundedCornerPlaceHolder", "coilRoundingRadius"],
)
fun ImageView.setCoilRoundedCornerImageWithUri(
url: String?,
uri: Uri?,
placeHolder: Drawable? = null,
roundingRadius: Float,
) {
val image = uri ?: url
load(image) {
placeholder(placeHolder)
transformations(RoundedCornersTransformation(roundingRadius))
error(placeHolder)
}
}

@BindingAdapter(
value = [
"colorImageResource",
"grayImageResource",
],
)
fun ImageView.setImageResourceWithId(
colorResId: Int,
grayResId: Int,
) {
setImageResource(
if (isSelected) {
colorResId
} else {
grayResId
},
)
}
Loading