Skip to content

Main 홈, 스크롤

yunso edited this page Jan 15, 2021 · 5 revisions

🔥 Main 화면 구성 (홈 + 스크롤)

  • 해당 디렉토리로 이동하기
  • viewPager2를 이용해 2개의 프래그먼트를 vertical scroll로 연결하였습니다.
  • ScrollFragment에서 스크롤시 viewPager2가 스크롤되는 것을 막기 위하여 NestedScrollableHost를 이용해 자식 뷰의 스크롤을 우선 인식할 수 있도록 설정했습니다.

fragment_home.xml

<com.example.momo_android.util.ui.NestedScrollableHost
    android:id="@+id/nestedScrollableHost"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView_gradient"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        tools:listitem="@layout/item_scroll_gradient" />

</com.example.momo_android.util.ui.NestedScrollableHost>

🔥 HomeFragment

✔️ Empty & Diary view

  • 사용자가 현재 일자에 업로드한 일기가 없을 경우, 비어있는 홈 화면을 보여주고
    현재 일자에 이미 일기를 업로드했을 경우 해당 일기 정보를 보여줍니다.

HomeFragment.kt

private fun setServerDiaryData(diaryList: List<ResponseDiaryList.Data>) {
    when (diaryList.size) {
        0 -> {
            setEmptyView()
            DIARY_STATUS = false
        }
        else -> {
            setDiaryView()
            DIARY_STATUS = true
            diaryId = diaryList[0].id
            setEmotionData(diaryList[0].emotionId, isDay)
            setDepthData(diaryList[0].depth)
            setBookDiaryData(diaryList[0])
        }
    }
    fadeOutLoadingView()
}

✔️ Day & Night mode

  • 현재 시간을 바탕으로 06:00 ~ 18:59 까지는 Day mode,
    그 이외의 시간에는 Night mode의 UI를 보여줍니다.

HomeFragment.kt

private fun setDayNightStatus() {
    val currentHourDay = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) // 24시간 포맷
    if (currentHourDay in 6..18) { // 06:00 ~ 18:59
        setDayView()
        isDay = true
    } else {
        setNightView()
        isDay = false
    }
    setLoadingViewBackground()
}

✔️ Refresh server data

  • 다이어리 상세 뷰에서 수정을 한 후, 다시 홈 화면으로 돌아왔을 때 IS_EDITED boolean 값을 이용해 데이터를 다시 로드합니다.

HomeFragment.kt

override fun onResume() {
    super.onResume()
    if(IS_EDITED) {
        updateByServerData()
        IS_EDITED = false
    }
}


🔥 ScrollFragment

✔️ 그라디언트 및 오브제로 이루어진 깊이 배경 아이템 배치

  • 총 7개의 깊이 단계에 각기 다른 백그라운드를 적용하기 위해 각 단계를 recyclerView의 한 아이템으로 구성했습니다.

ScrollFragment.kt

private fun setGradientRecyclerView(year: Int, month: Int) {
    viewBinding.recyclerViewGradient.apply {
        adapter = ScrollGradientAdapter(year, month)
        layoutManager = LinearLayoutManager(requireContext())
        addOnScrollListener(scrollListener)
    }
}

  • 뷰홀더에서 그라디언트 아이템이 바인딩될 때, viewStub을 이용하여 동적으로 배경 리소스를 교체하였습니다.

ScrollGradientViewHolder.kt

private fun setDepthViews(position: Int) {
    viewBinding.apply {
        constraintLayout.removeAllViews()
        when (position) {
            0 -> {
                textViewDepth.text = "2m"
                viewStubGradient.layoutResource = R.layout.view_stub_depth_1
            }
            1 -> {
                textViewDepth.text = "30m"
                viewStubGradient.layoutResource = R.layout.view_stub_depth_2
            }
            2 -> {
                textViewDepth.text = "100m"
                viewStubGradient.layoutResource = R.layout.view_stub_depth_3
            }
            3 -> {
                textViewDepth.text = "300m"
                viewStubGradient.layoutResource = R.layout.view_stub_depth_4
            }
            4 -> {
                textViewDepth.text = "700m"
                viewStubGradient.layoutResource = R.layout.view_stub_depth_5
            }
            5 -> {
                textViewDepth.text = "1,005m"
                viewStubGradient.layoutResource = R.layout.view_stub_depth_6
            }
            6 -> {
                textViewDepth.text = "심해"
                viewStubGradient.layoutResource = R.layout.view_stub_depth_7
            }
        }
        constraintLayout.addView(viewBinding.viewStubGradient)
        constraintLayout.addView(viewBinding.textViewDepth)
        constraintLayout.addView(viewBinding.recyclerViewOval)
        viewStubGradient.inflate()
    }
}

✔️ 스와이프 아이콘 상태 전환

  • 스크롤 중에는 스와이프 아이콘이 보이지 않다가 스크롤을 멈췄을 때 스와이프 아이콘이 보여집니다.

ScrollFragment.kt

private val scrollListener = object : RecyclerView.OnScrollListener() {
    @RequiresApi(Build.VERSION_CODES.N)
    override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
        super.onScrollStateChanged(recyclerView, newState)
        when (newState) {
            SCROLL_STATE_IDLE -> fadeInSwipeImage()
            SCROLL_STATE_DRAGGING -> fadeOutSwipeImage()
        }
    }
}