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: add scroll action in ProfileFragment #158

Merged
merged 26 commits into from
Jan 31, 2024
Merged

Conversation

HeewonP825
Copy link
Collaborator

Related Issue

#25

Changes

작업 사항

  • ProfileFragment의 전체 화면 ScrollView 구현 완료
    • ScrollViewRecyclerView, TabLayout의 중첩 스크롤 문제로 인해 NestedScrollView 사용
    • ViewPager2 제거 후 프로필 페이지에서 직접 RecyclerView 사용
    • SwipeRefresh 추가
    • ProfileTapRvDataHelper로 메서드 추출/분리 완료
  • backbtn에 TimeLineFragment로 이동하는 action 추가

수정 사항

  • Theme/colors 파일에 정의된 색상 테마 추가 및 수정
    • Red->PinkRed 추가

Screenshots

작업화면

To Reviewer

TODO

  • Highlight 탭에서 보여주는 유료구독페이지는 따로 RV로 만들어서 추후 적용해보겠습니당...로직이 좀 꼬이네요ㅜ
  • 스크롤 시 headerTabLayout 고정하는 부분은 에디터 만든 이후에 만들겠습니당,,ㅎㅎㅎㅎ

Checklist

  • PR 제목은 포맷과 내용 둘 다 알맞게 작성되었는가
  • PR에 대해 구체적으로 설명이 되어있는가

@HeewonP825 HeewonP825 added android 안드로이드 관련 내용을 다룰 때 사용됩니다 feature 새로운 기능을 만들 때 사용됩니다 labels Jan 31, 2024
@HeewonP825 HeewonP825 self-assigned this Jan 31, 2024
@HeewonP825 HeewonP825 requested a review from poiu694 as a code owner January 31, 2024 02:23
Copy link
Collaborator

@poiu694 poiu694 left a comment

Choose a reason for hiding this comment

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

리뷰 남겼습니다 ! 고생하셨어요 :)

// (binding.rvProfile.adapter as? TimelineRecyclerViewAdapter)?.updateData(shuffledTimelineList)
//
// binding.swipeRefreshLayout.isRefreshing = false
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

eol :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

551ee38 eol 모두 처리해서 반영했습니다!

Comment on lines 196 to 201
fun refreshTimelineData() {
//val shuffledTimelineList = ProfileTapRvDataHelper.getDataForTab().shuffled()
// (binding.rvProfile.adapter as? TimelineRecyclerViewAdapter)?.updateData(shuffledTimelineList)
//
// binding.swipeRefreshLayout.isRefreshing = false
}
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.

swipe action을 통해 데이터를 리프레쉬 시킬 때 사용할 함수인데 메서드 추출로 인해 클래스를 분리한 상태입니다! ProfileFragment의 코드에 이 함수를 사용하는 부분이 있고 추후 binding 부분을 바꾸어 처리할 예정이라 내용만 주석처리해두었습니다:)

Copy link
Collaborator

Choose a reason for hiding this comment

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

죠습니다 👍

data class HighlightItem(
val title: String,
val description: String,
val btnText: String // 예시로 이미지 URL을 사용하였습니다. 실제 프로젝트에 맞게 변경하세요.
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.

Highlight 탭에서 보여주는 유료구독페이지를 예전처럼 ViewPager2가 아닌 RecyclerView로 보여줘야 하기때문에 Data ClassAdapter를 만들어서 보여주는 방법을 시도해본건데 GPT한테 부탁한 코드를 그대로 복사해서 주석을 안지웠네용..ㅎㅎ 지웠습니다!!ㅎㅎㅎ

Copy link
Collaborator

Choose a reason for hiding this comment

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

죠습니다~!!

return highlightList.size
}

}
Copy link
Collaborator

Choose a reason for hiding this comment

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

eol :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

551ee38 eol 모두 처리해서 반영했습니다!

Comment on lines 58 to 86
if (e.action == MotionEvent.ACTION_DOWN) {
initialX = e.x
initialY = e.y
parent.requestDisallowInterceptTouchEvent(true)
} else if (e.action == MotionEvent.ACTION_MOVE) {
val dx = e.x - initialX
val dy = e.y - initialY
val isVpHorizontal = orientation == ORIENTATION_HORIZONTAL

// assuming ViewPager2 touch-slop is 2x touch-slop of child
val scaledDx = dx.absoluteValue * if (isVpHorizontal) .5f else 1f
val scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5f

if (scaledDx > touchSlop || scaledDy > touchSlop) {
if (isVpHorizontal == (scaledDy > scaledDx)) {
// Gesture is perpendicular, allow all parents to intercept
parent.requestDisallowInterceptTouchEvent(false)
} else {
// Gesture is parallel, query child if movement in that direction is possible
if (canChildScroll(orientation, if (isVpHorizontal) dx else dy)) {
// Child can scroll, disallow all parents to intercept
parent.requestDisallowInterceptTouchEvent(true)
} else {
// Child cannot scroll, allow all parents to intercept
parent.requestDisallowInterceptTouchEvent(false)
}
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 부분도 if가 너무 중첩이라서요! 개선해 보면 어떨까요?

fun moveAction(x: Number, y: Number) {
    val dx = x - initialX
    val dy = y - initialY
    val isVpHorizontal = orientation == ORIENTATION_HORIZONTAL

    // assuming ViewPager2 touch-slop is 2x touch-slop of child
    val scaledDx = dx.absoluteValue * if (isVpHorizontal) .5f else 1f
    val scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5f

    if (scaledDx <= touchSlop && scaledDy <= touchSlop)  {
        return
    }

    val isVerticalGesture = scaledDy > scaledDx
    if (isVpHorizontal == isVerticalGesture)  {
        // Gesture is perpendicular, allow all parents to intercept
        parent.requestDisallowInterceptTouchEvent(false)
        return
    }
    parent.requestDisallowInterceptTouchEvent(canChildScroll(orientation, if (isVpHorizontal) dx else dy)
}

if (e.action == MotionEvent.ACTION_DOWN) {
    downAction(e.x, e.y)
}
if (e.action == MotionEvent.ACTION_MOVE) {
    moveAction(e.x, e.y)
}

이런 느낌으로도 될까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

원래 ViewPager2를 사용하면서 여기정기 방법을 찾아서 구글링 하던 도중에 NestedScrollView를 사용하기 위해서 이 클래스를 레포에 넣으라고 해서 넣었던 코드인데.. 결과적으로 그 코드를 사용하지 않게되었는데 깜빡하고 지우지를 못했네요ㅜ 삭제하고 각 fragment_xxx.xml에서 사용했던 부분도 삭제 처리 완료했습니다!:) 8a45fab

Copy link
Collaborator

Choose a reason for hiding this comment

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

좋습니당 :)

Comment on lines 152 to 169
if (e1 != null && e2 != null) {
val deltaX = e2.x - e1.x
val deltaY = e2.y - e1.y
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// 가로로 스와이프된 경우
if (Math.abs(deltaX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (deltaX > 0) {
// 오른쪽으로 스와이프한 경우
navigateToPreviousTab()
} else {
// 왼쪽으로 스와이프한 경우
navigateToNextTab()
}
return true
}
}
}
return false
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기도 아래처럼 하면 좋을 것 같아요 :)

if (e1 == null || e2 == null)
    return false
val deltaX = Math.abs(e2.x - e1.x)
val deltaY = Math.abs(e2.y - e1.y)

if (deltaX < deltaY)
    return false
if (Math.abs(deltaX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
     if (deltaX > 0) {
         // 오른쪽으로 스와이프한 경우
         navigateToPreviousTab()
     } else {
         // 왼쪽으로 스와이프한 경우
         navigateToNextTab()
     }
     return true
 }

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ff578c2 이 부분도 최대한 메서드로 분리해서 리뷰해주신 부분 반영 완료했습니다ㅎㅎ

gestureDetectorTab = GestureDetector(requireContext(), object : GestureDetector.SimpleOnGestureListener() {
            override fun onFling(
                e1: MotionEvent?,
                e2: MotionEvent,
                velocityX: Float,
                velocityY: Float
            ): Boolean {
                return handleSwipe(e1, e2, velocityX)
            }
        })
fun handleSwipe(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float): Boolean {
        if (e1 != null && e2 != null) {
            val deltaX = e2.x - e1.x
            val deltaY = e2.y - e1.y
            return handleHorizontalSwipe(deltaX, deltaY, velocityX)
        }
        return false
    }

    private fun handleHorizontalSwipe(deltaX: Float, deltaY: Float, velocityX: Float): Boolean {
        val absDeltaX = abs(deltaX)
        val absDeltaY = abs(deltaY)

        if (absDeltaX > absDeltaY && absDeltaX > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
            if (deltaX > 0) {
                // 오른쪽으로 스와이프한 경우
                navigateToPreviousTab()
            } else {
                // 왼쪽으로 스와이프한 경우
                navigateToNextTab()
            }
            return true
        }
        return false
    }


val currentTab = tabLayout.selectedTabPosition
if (currentTab < tabTitles.size - 1) {
tabLayout.getTabAt(currentTab + 1)?.select()
Copy link
Collaborator

Choose a reason for hiding this comment

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

아래처럼 작성하면 if문 다이어트를 할 수 있지 않을까요?

tabLayout.getTabAt(Math.min(currentTab + 1, tabTitles.size - 1))?.select()

Comment on lines 317 to 319
if (currentTab > 0) {
tabLayout.getTabAt(currentTab - 1)?.select()
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

아래처럼 작성하면 if문 다이어트를 할 수 있지 않을까요? 22

tabLayout.getTabAt(Math.max(currentTab - 1, 0))?.select()

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

tabLayout.getTabAt((currentTab - 1).coerceAtLeast(0))?.select()

반영완료했습니다!

Comment on lines +322 to +325
companion object {
private const val SWIPE_THRESHOLD = 100
private const val SWIPE_VELOCITY_THRESHOLD = 100
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

상수화 👍

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView9" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copy link
Collaborator

Choose a reason for hiding this comment

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

eol :)

Copy link
Collaborator

@poiu694 poiu694 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다 👍

@HeewonP825 HeewonP825 merged commit 1e3e8d1 into android/dev Jan 31, 2024
1 check passed
@HeewonP825 HeewonP825 deleted the feat/profile-scroll branch January 31, 2024 11:05
HeewonP825 added a commit that referenced this pull request Feb 22, 2024
* feat: add start & login fragment for android (#26)

* feat: setting android development environment

* feat: setting navigation graph

* feat: setting ktlint

* feat: setting ktlint

* feat: setting ktlint

* chore: test eol at new file

* chore: add eol to files

* chore: add eol to gitignore

* chore: add colorList

* chore: add font_resource & font_style xml

* chore: add font style themes

* chore: edit theme colors

* chore: edit font style themes

* feat: add startFragment & edit MainActivity, nav_graph

* feat: add lottieAnimation in Gradle & startFragment

* feat: edit lottieAnimation size

* chore: add icons

* feat: add loginFragment & strings

* feat: add nagivation start to login & loginFragment ui xml

* feat: add String and edit login & loginFragment ui xml

* feat: add nagivation login to password  & PasswordFragment ui xml

* chore: edit letterspacing in themes.xml

* chore: review apply

* chore: edit home icon

* feat: add find account Fragment & edit font system in themes (#35)

* chore: add green check icon

* feat: add FindAccountFragment

* feat: edit FindAccountFrangmet for basic setting

* feat: add FindAccountFragment String

* feat: add navigation action in loginFragment & PasswordFragment

* chore: edit font system in themes

* chore: edit textStyle in fragment_password

* feat: add CheckIdFragment

* feat: delete checkidFragment & edit FindAccountFragment btn ui & add underline for passwordFragment string

* feat: edit id name in login/findAccount Fragment

* feat: edit headline weight in fragments

* chore: edit textStyle & delete view in startFragment

* feat: finish login & join View components (#58)

* feat: add createAccountFragment

* feat: add string for createAccountFragment

* feat: edit xml for CreateAccountFragment Ui

* feat: add navigation Action for createAccountFragment

* feat: add action for check icon in CreateAccountFragment

* feat: edit string for CreatAccountFragment

* chore: add icons for password/profile

* feat: edit textcolor for announcement & add toast message

* feat: add SendCodeFragment

* feat: add strings for SendCodeFragment

* feat: add navigation Action for SendCodeFragment

* feat: edit xml & fragment code for SendCodeFragment

* feat: edit string to remove phoneNum & add email/Number Keypad for editText

* feat: add NeedPasswordFragment

* feat: add strings for NeedPasswordFragment

* feat: edit xml & fragment code for NeedPasswordFragment

* feat: add navigation Action for NeedPasswordFragment

* feat: edit directory structure for viewmodel(MVVM) & add JoinViewModel

* feat: add ProfileImageFragment

* feat: add string for ProfileImageFragment

* feat: edit xml & fragment code for ProfileImageFragment

* feat: add navigation Action for ProfileImageFragment

* feat: add Fragment & string for AskNameFragment

* feat: edit xml & fragment code for AskNameFragment

* feat: add navigation Action for AskNameFragment

* feat: remove skip btn in AskNameFragment

* feat: edit JoinViewModel for send livedata fragment to fragment

* feat: edit NeedPasswordFragment to Setting icon action for password inputType On/Off

* feat: edit profileImageFragment to link icon to Gallery

* feat: forbid keybord action(space, enter)

* feat: edit PasswordFragment to Setting icon action for password inputType On/Off

* feat: add viewmodel for login View

* feat: add button activation for all fragments

* feat: change lottie animation

* feat: remove underline in EditText

* feat: add hint animation in join View

* feat: add hint animation in login View

* feat: add validate check for NeedPasswordFragment & add Toast for sendEmail

* feat: add validate check for CreateAccountFragment

* feat: edit ImageView to CardView

* feat: add Image delete btn & logic in ProfileImageFragment

* feat: add keypad dependency in buttons

* feat: edit viewmodel to bundle in login->password logic

* feat: edit FindAccountFragment to remove underline in editText

* feat: remove log

* chore: reflect review

* feat: edit eol

* feat: add toolbar & bottom navigation bar (#71)

* feat: add toolbar & navigation bar basic setting

* feat: change constraintLayout into LinearLayout to pix location & add TimelineFragment

* feat: edit toolbar navigate icon & actions for login/join Views

* feat: setting basic things for timelineFragment

* feat: add toolbar icon in TimelineFragment

* feat: create Fragments for add bottom navigation bar

* feat: edit activity_main.xml for toolbar/navbar/fragmentContainer view problem

* feat: edit margin in loginFragment

* edit bottom_nav

* feat: chained fragmentContainerView in activityMain

* feat: edit toolbar & bottom navigationbar

* feat: delete sucks itemActiceIndicator

* feat: clear doubleClicked icon focus issue

* chore: add eol

* chore: reflect review

* chore: reflect review

* chore: reflect review

* feat: add RecyclerView & TabLayout in TineLine Fragment (#78)

* chore: edit nav_bar visibility for easy dev

* feat: add profile icon for toolbar

* feat: add action for profile icon to navigate ProfileFragment

* feat: add adapter for TimelineFragment & add Tablayout/ViewPager

* feat: add ForToyFragment/TimeLineFragment & edit toolbar bg/indicator color

* feat: add item_timeline for timeline RecyclerView

* feat: edit item_timeline for timeline RecyclerView

* feat: edit TimeLineItem dataclass for nullable components

* feat: add recyclerView in FollowingFragment

* feat: edit profileImg to nullable & remove touch animation in bottombar

* feat: add scroll action save logic in RV

* feat: add json file & edit icon size

* chore: add icons for post menu

* feat: edit TimelineRVAdapter

* feat: add bottomSheetDialog & Menu & FAB (#114)

* feat:add bottomSheetDialog for Timeline

* feat:add bottomSheetDialog xml for Timeline

* feat: add behavior navigationBar & edit bottomsheet

* feat: add fab btn & animation in timeline Fragment

* feat: add fab btn & animation in timeline Fragment

* fix: edit Viewpager overFlow

* fix:remove bottomSheetDialog

* feat: edit fab margin in constraintlayout

* feat: add dummy data for Timeline

* feat: add fab in navigation Fragment

* feat: edit fab in messageFragment

* feat: add vibrate for longClick

* feat: add icons for popupmenu & add basic popupMenu

* feat: add custom popup menu xml

* feat: add custom popup into TimeLineRVAdapter

* feat: edit custom popup tv

* feat: add bottomSheetDialog

* chore: rename Timeline package to timeline

* feat: add post Fragment

* feat: add navigation actions to post Fragment

* feat: add actions for fab to PostFragment

* fix: fix navigation actions to post Fragment

* feat: add xml for ProfileFragment

* feat: add action in MypageFragment(before ProfileFragment)

* feat: add toggle action in MypageFragment

* feat: add lightMode icon & Toast

* feat: try to add animation in MyPageFragment

* feat: add overlay view in TimelineFragment

* feat:divide bottomSheetDialog into Rt & share

* feat: add Toast into MyPageFragment

* feat: add ViewBottomSheetDialog

* feat: edit button to android.widget.button

* chore: add eol

* chore: reflect review

* chore:reflect review

* feat: add ic_up_arrow

* chore:reflect review

* feat: fix FAB animation bug

* chore:reflect review

* feat: remove elevation in bottomSheet btn

* feat: add ProfileFragment & BookMarkFragment (#121)

* feat: add profileFragment.xml before tablayout

* feat: add viewPager & TabLayout in ProfileFragment

* feat: add RV in MyPostFragment & edit doublePressed Logic in ForYou/Following Fragment

* feat: add RV in ReplyFragment

* feat: add RV in LikedFragment

* feat: add RV in MediaFragment

* feat: add RV in HighlightFragment

* feat: change scrollview into NestedScrollView

* feat: try to change statusBar Transperent

* feat: add naviation for ProfileFragment & ViewPager

* feat: Edit HighlighFragment to subscribe xml

* feat: add FAB in ProfileFragment

* feat: edit toobal & navBar visibility

* feat: add BookMarkFragment & nav Actions

* feat: add RV & toolbar Visibility for BookMarkFragment

* feat: add layout for when bookMark is empty

* feat: edit navigation in MyPageFragment

* chore: add icon

* chore: add eol

* feat: add scroll action in ProfileFragment (#158)

* chore: remove unused behavior.kt

* feat: add SwipeRefresh in Timeline

* feat: try to forbid basicBackbtn in ProfileFragment

* feat: add nestedScrollableHost/icon  & edit color theme name

* chore: add Timber in Dependency & MainActivity

* feat: remove scrollView in RV

* feat: remove scrollView in RV

* feat: remove scrollView in RV

* feat: divide ConstraintLayout into 2

* feat: edit xml for scrollView

* feat: add action in backbtn for ProfileFragment

* feat: add SwipeRefresh in xml

* feat: add swipe action in Tablayout

* extract Method for RV in ProfileFragment

* feat: try to add Highlight RV for ProfileFragment Tablayout

* feat: make FAB cannot scroll

* chore:add eol

* feat: edit popupMenu constraintLayout

* chore: add eol

* chore: reflect review

* chore: reflect review

* chore: reflect review

* chore: reflect review

* chore: reflect review

* chore: add eol

* chore: add eol

* feat: add PostFragment (#234)

* feat: remove toolbar&navigation in PostFragment

* feat: edit fragment_post.xml

* feat: edit post_fragment.xml

* feat: add textWatcher action & photo plus btn in PostFragment

* feat: add CircularProgressBar

* feat: add CircularProgressBar

* fix: edit constraintLayout for editText space

* fix: add img RV in PostFragment

* fix: add horizontalScrollView

* feat: link Gallery to PostFragment RV with Glide

* feat: add border & cardView in Item_post_img

* feat: add action for backbtn in PostFragment

* chore:edit opacity for popup menu

* feat: load Img from gallery to PostFragment

* feat: change view's ConstraintLayout in PostFragment

* feat: change enable btn in postFragment

* feat: change deleteBtn translationZ

* fix: fix upload sequence error

* feat: add setOnClickListener in Horizontal RV

* feat: change enable btn in postFragment

* feat: change enable btn when add img in postFragment

* chore:reflect review

* chore:reflect review

* chore:reflect review

* chore:reflect review

* feat: add quote & detail fragment (#279)

* feat: add quote text & image ver

* feat: add MultiView(quote text & image) in RV

* feat: edit MultiView(quote text & image) margin & border in RV

* feat: set Visibility for MultiView(quote text & image) in RV

* feat: add margin for MultiView(quote text & image) in RV

* feat: add postDetailFragment

* feat: add item_post_detail.xml

* feat: edit item_post_detail.xml

* feat: add api for login&join (#292)

* feat:add api(users/verify-email, users/temporary-join)

* feat:add api(auth)

* feat:add api(user/join) except profileImg

* feat:add api(auth/mobile) & tokenManager

* feat:add api(users/me)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android 안드로이드 관련 내용을 다룰 때 사용됩니다 feature 새로운 기능을 만들 때 사용됩니다
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants