๊ณต๋ถํ ๊ฒ
- Retrofit2, OkHttpLoggingInterceptor
- Shimmer
- Glide
- Content Resolver
- Unsplash API
์๊ฒ๋ ๊ฒ
1. Glide
์ค๋ ๊ณต๋ถ๋ฅผ ํ๋ฉด์ Glide
๊ฐ ์๊ฐ๋ณด๋ค ์์ฒญ ๊ฐ๋ ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ผ๋ ๊ฒ์ ๊นจ๋ฌ์๋ค. Glide
๋ฅผ ์ฌ์ฉํ์ง๋ ๊ฝค ๋์ง๋ง ์ด๋ฅผ ์ ๋๋ก
์ฌ์ฉํ๊ณ ์์ง ์์๋ค. ์ฐ์ ๊ทธ๋์ Glide
๋ฅผ ์ฌ์ฉํ ๋ ์๋์ฒ๋ผ ์จ์๋ค. ๊ทธ๋ฅ ๋จ์ํ ์ด๋ฏธ์ง๋ทฐ์ ์ด๋ฏธ์ง๋ฅผ ๋ฃ์ด์ฃผ๊ธฐ ์ํ ์ฉ๋๋ก...
private fun bindViews() {
Glide.with(binding.root)
.load(profileImageUrl)
.into(binding.profileImageView)
}
ํ์ง๋ง ์ ๋ง ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์์๋ค.
์ฐ์ ์ฒซ ๋ฒ์งธ, Placeholder
์ ํ๋ธ ์ฑ์ ์ ์ํ๋ฉด ์ด๊ธฐ์ ๋ฆฌ์์ค๋ฅผ ๋ค ๋ถ๋ฌ์ค์ง ๋ชปํ์ ๋ ๋น ๋ ์ด์์์ด ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ๋ ์ด์์ ์์ฒด์ ์์ฑ์ ๋ถ์ฌํด์ ์ด๋ฅผ ๊ตฌํํ ์ ์์ง๋ง Glide
์ Placeholder
๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค. ๋ฆฌ์์ค๋ฅผ ๋ถ๋ฌ์ค์ง ๋ชปํ ๊ฒฝ์ฐ drawable
๋ก ๋จผ์ ๋ณด์ฌ์ฃผ๊ณ ๋ฆฌ์์ค๋ฅผ ๋ถ๋ฌ์จ ๊ฒฝ์ฐ์ ์ด๋ฅผ ๋์ฒดํ๋ค. error
์ fallback
๋ ์ง์ํ๋ค.
private fun bindViews() {
Glide.with(binding.root)
.load(profileImageUrl)
.placeholder(R.drawable.shape_profileImage_placeholder)
.into(binding.profileImageView)
}
๋ ๋ฒ์งธ, thumbnail
Unsplash API
์์ ํ์ง์ ๋ฐ๋ฅธ ๋ค์ํ ์ด๋ฏธ์ง Url
์ ์ ๊ณตํ๋ค. ๊ณ ํ์ง์ ๊ฒฝ์ฐ ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์ค๋๋ฐ ๋ณด๋ค ์ค๋ ์๊ฐ์ด ์์๋๋๋ฐ ๋ณ๋์ ์ฒ๋ฆฌ๋ฅผ ํ์ง ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ ๋ถํธํจ์ ๋๋ ์ ์๋ค. ์ด๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์๋ ProgressBar
๋ฅผ ํ์ํ๋ ๋ฐฉ๋ฒ์ด ์ผ๋ฐ์ ์ด์ง๋ง thumbnail
์ ํ์ฉํ๋ฉด ๋ ํจ๊ณผ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค. thumbnail
์ ์ ํด์๋ ์ด๋ฏธ์ง๋ฅผ ๋น ๋ฅด๊ฒ ๋ก๋ํ์ฌ ๋ณด์ฌ์ค๋ค. ํ์ง๋ง ์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ๊ตฌํํด์ผ ํ๋ ๊ฒ์ด ์๋๋ฐ ์ ํด์๋ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ฅผ ๋ง์ถฐ์ฃผ๋ ๊ฒ์ด๋ค. ๋จ์ํ thumbnail
๋ง ์ฌ์ฉํ๋ฉด ์ด๋ฏธ์ง์ ํฌ๊ธฐ๊ฐ ์ฒ์์๋ ์์๋๋ฐ ๋ก๋๊ฐ ์๋ฃ๋๋ฉด ๊ณ ํด์๋ ์ด๋ฏธ์ง์ ๋ง๊ฒ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ฒ ๋๋ค. ๋ฐ๋ผ์ ์ด๋ฏธ์ง์ ๋น์จ์ ๋ง์ถฐ ์ ํด์๋ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ฅผ ์ฌ์กฐ์ ํด์ฃผ๋ ์์
์ ์ฐ์ ์ ์ผ๋ก ์งํํ๋ค.
val dimensionRatio = photo?.height!! / photo?.width?.toFloat()!!
val targetWidth = binding.root.resources.displayMetrics.widthPixels - (binding.root.paddingStart + binding.root.paddingEnd)
val targetHeight = (targetWidth * dimensionRatio).toInt()
binding.contentsContainer.layoutParams = binding.contentsContainer.layoutParams.apply {
height = targetHeight
}
์ด๋ฏธ์ง ๋น์จ์ ๋ง์ถฐ ์ ํด์๋ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ฅผ ๊ณ ํด์๋ ์ด๋ฏธ์ง์ ํฌ๊ธฐ์ ๋์ผํ๊ฒ ๋ง์ถฐ์คฌ๋ค๋ฉด thumbnail
์ ๋ฃ์ด์ค๋ค. transition
์ ์์ฒญ์ด ์๋ฃ๋ ๋์ ์ ๋๋ฉ์ด์
ํจ๊ณผ๋ฅผ ์๋ฏธํ๋ค.
private fun bindViews() {
Glide.with(binding.root)
.load(profileImageUrl)
.thumbnail(
Glide.with(binding.root)
.load(profileImageLowUrl)
.transition(DrawableTransitionOptions.withCrossFade())
.override(targetWidth, targetHeight)
.placeholder(R.drawable.shape_profileImage_placeholder)
.into(binding.profileImageView)
}
์ธ ๋ฒ์งธ, Transformations
์ด๋ฏธ์ง๋ฅผ ๋ ์ด์์์ ๋ง๊ฒ ๋ค์ํ ํํ๋ก ์กฐ์ ํ ์ ์๋ค. CentorCrop, FitCenter, CircleCrop
3๊ฐ์ง๋ฅผ ์ง์ํ๋ค.
private fun bindViews() {
Glide.with(binding.root)
.load(profileImageUrl)
.placeholder(R.drawable.shape_profileImage_placeholder)
.circleCrop()
.into(binding.profileImageView)
}
2. Shimmer
ํ์ด์ค๋ถ์์ ์ ๊ณตํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค. ๋ฐ์ดํฐ ์์ฒญ์ด ์๋ฃ๋๊ธฐ ์ ์ ์์๋ก ๋น ๋ ์ด์์์ ๋ณด์ฌ์ฃผ๋๋ฐ ๋ฐ์ง๋ฐ์ง
๊ฑฐ๋ฆฌ๋ ํจ๊ณผ๋ฅผ ๋ถ์ฌํ ์ ์๋ค. ์ ํ๋ธ์ฑ์์ ํด๋น ํจ๊ณผ๋ฅผ ์ฐพ์๋ณผ ์ ์๋ค.
์์กด์ฑ์ ์ถ๊ฐํ๋ค.
implementation 'com.facebook.shimmer:shimmer:0.5.0'
ํจ๊ณผ๋ฅผ ๋ฃ์ ๋ ์ด์์์ ShimmerLayout ์ผ๋ก ๊ฐ์ผ๋ค.
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/shimmerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/shimmer_item_photo" />
<include layout="@layout/shimmer_item_photo" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
๊ณต๋ถํ ๊ฒ
์๊ธฐ ์ ์ Live Data
๋ณด๊ณ ์๊ธฐ.
๋๋ ์
๋ํผ๋ฐ์ค ์ด์ฆ ํน. ๋ํผ๋ฐ์ค ์์ฃผ๋ก ๊ณต๋ถํ์.
'๐ป ๊ฐ๋ฐ > iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TIL] 22.03.19 (0) | 2022.03.19 |
---|---|
[TIL] 22.03.17 (0) | 2022.03.17 |
[TIL] 22.03.15 (0) | 2022.03.15 |
[TIL] 22.03.14 (0) | 2022.03.14 |
[TIL] 22.03.13 (0) | 2022.03.13 |