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

[feat] 랭킹 뷰 구현 #190

Merged
merged 19 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.sopt.pingle.domain.model

data class RankingEntity(
val meetingCount: Int,
val locations: List<RankingLocationEntity>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.pingle.domain.model

data class RankingLocationEntity(
val name: String,
val latestVisitedDate: List<Int>,
val locationCount: Int
)
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package org.sopt.pingle.presentation.ui.main.mypingle

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import org.sopt.pingle.databinding.ItemMyPingleBinding
import org.sopt.pingle.domain.model.MyPingleEntity
import org.sopt.pingle.util.view.ItemDiffCallback

class MyPingleAdatper(
private val context: Context,
class MyPingleAdapter(
private val showCancelModalDialogFragment: (MyPingleEntity) -> Unit,
private val showDeleteModalDialogFragment: (MyPingleEntity) -> Unit,
private val updateMyPingleListSelectedPosition: (Int) -> Unit,
Expand All @@ -29,7 +27,7 @@ class MyPingleAdatper(

false
),
context,
parent.context,
showCancelModalDialogFragment,
showDeleteModalDialogFragment,
updateMyPingleListSelectedPosition,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import org.sopt.pingle.util.view.UiState
@AndroidEntryPoint
class MyPingleFragment : BindingFragment<FragmentMyPingleBinding>(R.layout.fragment_my_pingle) {
private val viewModel by viewModels<MyPingleViewModel>()
private lateinit var myPingleAdapter: MyPingleAdatper
private lateinit var myPingleAdapter: MyPingleAdapter

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Expand All @@ -41,8 +41,7 @@ class MyPingleFragment : BindingFragment<FragmentMyPingleBinding>(R.layout.fragm
}

private fun initLayout() {
myPingleAdapter = MyPingleAdatper(
requireContext(),
myPingleAdapter = MyPingleAdapter(
showCancelModalDialogFragment = ::showCancelModalDialogFragment,
showDeleteModalDialogFragment = ::showDeleteModalDialogFragment,
updateMyPingleListSelectedPosition = ::updateMyPingleListSelectedPosition,
Expand Down Expand Up @@ -122,7 +121,7 @@ class MyPingleFragment : BindingFragment<FragmentMyPingleBinding>(R.layout.fragm
textButtonText = stringOf(R.string.delete_modal_text_button_text),
clickBtn = { viewModel.deletePingleDelete(meetingId = myPingleEntity.id.toLong()) },
clickTextBtn = {}
).show(childFragmentManager, MY_PINGEL_DELETE_MODAL)
).show(childFragmentManager, MY_PINGLE_DELETE_MODAL)
}

private fun updateMyPingleListSelectedPosition(position: Int) {
Expand All @@ -142,6 +141,6 @@ class MyPingleFragment : BindingFragment<FragmentMyPingleBinding>(R.layout.fragm

companion object {
const val MY_PINGLE_CANCEL_MODAL = "MyPingleCancelModal"
const val MY_PINGEL_DELETE_MODAL = "MyPingelDeleteModal"
const val MY_PINGLE_DELETE_MODAL = "MyPingleDeleteModal"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.sopt.pingle.presentation.ui.main.ranking

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import org.sopt.pingle.databinding.ItemRankingBinding
import org.sopt.pingle.domain.model.RankingLocationEntity
import org.sopt.pingle.util.view.ItemDiffCallback

class RankingAdapter :
ListAdapter<RankingLocationEntity, RankingViewHolder>(
ItemDiffCallback<RankingLocationEntity>(
onItemsTheSame = { old, new -> old.name == new.name },
onContentsTheSame = { old, new -> old == new }
)
) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RankingViewHolder =
RankingViewHolder(
binding = ItemRankingBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
),
context = parent.context
)

override fun onBindViewHolder(holder: RankingViewHolder, position: Int) {
holder.onBind(rankingLocationEntity = getItem(position), ranking = position + 1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,41 @@ package org.sopt.pingle.presentation.ui.main.ranking

import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import org.sopt.pingle.R
import org.sopt.pingle.databinding.FragmentRankingBinding
import org.sopt.pingle.util.base.BindingFragment

class RankingFragment : BindingFragment<FragmentRankingBinding>(R.layout.fragment_ranking) {
private val viewModel by viewModels<RankingViewModel>()
private lateinit var rankingAdapter: RankingAdapter

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

initLayout()
}

override fun onDestroyView() {
binding.rvRanking.adapter = null
super.onDestroyView()
}

private fun initLayout() {
rankingAdapter = RankingAdapter()
binding.rvRanking.adapter = rankingAdapter

// TODO 서버통신 구현 후 collectData 함수로 해당 로직 이동
with(viewModel.dummyRanking) {
(meetingCount >= RANKING_VISIBLE_THRESHOLD).let { isRankingVisible ->
if (isRankingVisible) rankingAdapter.submitList(locations)
binding.tvRankingEmpty.visibility =
if (isRankingVisible) View.INVISIBLE else View.VISIBLE
}
}
Comment on lines +29 to +36
Copy link
Member

Choose a reason for hiding this comment

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

미리 구현 굿굿

}

companion object {
const val RANKING_VISIBLE_THRESHOLD = 30
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.sopt.pingle.presentation.ui.main.ranking

import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import org.sopt.pingle.R
import org.sopt.pingle.databinding.ItemRankingBinding
import org.sopt.pingle.domain.model.RankingLocationEntity

class RankingViewHolder(private val binding: ItemRankingBinding, private val context: Context) :
RecyclerView.ViewHolder(binding.root) {
fun onBind(rankingLocationEntity: RankingLocationEntity, ranking: Int) {
with(binding) {
tvRankingRank.text = ranking.toString()
tvRankingLocationCount.text = rankingLocationEntity.locationCount.toString()
tvRankingLocationName.text = rankingLocationEntity.name
(rankingLocationEntity.latestVisitedDate).let { latestVisitedDate ->
tvRankingLocationDate.text = context.getString(
R.string.ranking_date,
latestVisitedDate[YEAR_INDEX],
latestVisitedDate[MONTH_INDEX],
latestVisitedDate[DAY_INDEX]
)
}
Comment on lines +17 to +23
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

이거 스트링으로 변경하는 과정 UI에서 하지 말기

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

-> 서버통신 구현하면서 수정 예정

}
}

companion object {
const val YEAR_INDEX = 0
const val MONTH_INDEX = 1
const val DAY_INDEX = 2
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.sopt.pingle.presentation.ui.main.ranking

import androidx.lifecycle.ViewModel
import org.sopt.pingle.domain.model.RankingEntity
import org.sopt.pingle.domain.model.RankingLocationEntity

class RankingViewModel() : ViewModel() {
val dummyRanking = RankingEntity(
meetingCount = 30,
locations = listOf(
RankingLocationEntity(
name = "솔트캐빈 화이트 용리단길점",
latestVisitedDate = listOf(2024, 1, 31),
locationCount = 20
),
RankingLocationEntity(
name = "하얀집 1호점",
latestVisitedDate = listOf(2024, 1, 31),
locationCount = 66
),
RankingLocationEntity(
name = "서울여자대학교 대학로캠퍼스",
latestVisitedDate = listOf(2024, 2, 17),
locationCount = 4
),
RankingLocationEntity(
name = "동국대학교 서울캠퍼스",
latestVisitedDate = listOf(2024, 2, 1),
locationCount = 100
),
RankingLocationEntity(
name = "국민대학교",
latestVisitedDate = listOf(2023, 12, 30),
locationCount = 13
),
RankingLocationEntity(
name = "IBK파이낸스타워",
latestVisitedDate = listOf(2023, 11, 12),
locationCount = 17
),
RankingLocationEntity(
name = "동탄시범다은마을월드메르디앙반도유보라아파트경비실",
Copy link
Collaborator

Choose a reason for hiding this comment

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

이게 대체 뭔데
ㅋ ㅋ
ㅋㅋ
ㅋㅋㅋ ㅋ ㅋ ㅋ

Copy link
Collaborator

Choose a reason for hiding this comment

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

ㄷㄷ 진짜 있네

image

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 두 줄 확인 해보려고 네이버에 이름 긴 아파트 검색했숨요 ㅋ.ㅋ

latestVisitedDate = listOf(2024, 1, 9),
locationCount = 2
)
)
)
}
12 changes: 12 additions & 0 deletions app/src/main/res/drawable/ic_ranking_pin_12.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<path
android:pathData="M10.5,5.444C10.5,7.899 7.688,11 6,11C4.313,11 1.5,7.899 1.5,5.444C1.5,2.99 3.515,1 6,1C8.485,1 10.5,2.99 10.5,5.444Z"
android:fillColor="#B7FF1D"/>
<path
android:pathData="M6,5.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
android:fillColor="#080909"/>
</vector>
68 changes: 42 additions & 26 deletions app/src/main/res/layout/fragment_ranking.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,57 @@
android:layout_height="match_parent"
tools:context=".presentation.ui.main.ranking.RankingFragment">

<TextView
Copy link
Collaborator

Choose a reason for hiding this comment

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

언니 이거 비밀인데 나 이제 가이드라인 쓸 줄 안다 ㅋ
혼자 해봤음ㅋ
칭찬해쥬삼

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

다 컸다 ㅋ.ㅋ 이제 내가 알려줄 게 없구만 ㅋㅋ UMC 레포 좀 알려줘봐요 ㅋㅋ 구경 좀 하게

android:id="@+id/tv_ranking_construction_title"
<androidx.constraintlayout.widget.Guideline
android:id="@+id/gl_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="137dp"
android:text="@string/construction_title"
android:textAppearance="@style/TextAppearance.Pingle.Title.Semi.24"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:orientation="vertical"
app:layout_constraintGuide_begin="@dimen/spacing16" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/gl_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="@dimen/spacing16" />

<TextView
android:id="@+id/tv_ranking_construction_detail"
android:id="@+id/tv_ranking_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:text="@string/construction_detail"
android:textAppearance="@style/TextAppearance.Pingle.Body.Semi.14"
android:layout_marginTop="31dp"
android:text="@string/ranking_title"
android:textAppearance="@style/TextAppearance.Pingle.Sub.Semi.18"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_ranking_construction_title" />
app:layout_constraintStart_toStartOf="@id/gl_start"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/iv_ranking_construction"
android:layout_width="wrap_content"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_ranking"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/gl_end"
app:layout_constraintStart_toStartOf="@id/gl_start"
app:layout_constraintTop_toBottomOf="@id/tv_ranking_title"
tools:listitem="@layout/item_ranking" />

<TextView
android:id="@+id/tv_ranking_empty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="42dp"
android:layout_marginTop="35dp"
android:src="@drawable/img_work_graphic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_ranking_construction_detail" />
android:layout_marginHorizontal="8dp"
android:gravity="center"
android:text="@string/ranking_empty"
android:textAppearance="@style/TextAppearance.Pingle.Sub.Semi.18"
android:textColor="@color/g_06"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/gl_end"
app:layout_constraintStart_toStartOf="@id/gl_start"
app:layout_constraintTop_toTopOf="@id/rv_ranking" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Loading
Loading