Conversation
kimdoyeon1234
left a comment
There was a problem hiding this comment.
과제 수행하시느라 정말 수고 많으셨습니다! 안드로이드에서 제공하는 기본 컴포넌트에 의존하지 않고, 직접 바텀바 구조부터 탭 전환 로직까지 하나하나 설계하고 구현해 보신 점이 정말 인상 깊어요!
..다만, 실제 협업이나 서비스 운영 관점에서 코드의 안정성과 유지보수성을 높일 수 있는 피드백을 몇 가지 드립니다. 확인하고 수정해주세요!
There was a problem hiding this comment.
바텀바를 LinearLayout으로 직접 구현하셨는데 이렇게는 잘 구현하지 않습니다 🥲 안드로이드 표준 라이브러리인 BottomNavigationView를 사용해 보시는 건 어떨까요? 아이콘 관리나 클릭 효과를 훨씬 쉽게 구현할 수 있습니다!
| val tab1 = view.findViewById<LinearLayout>(R.id.tab1) | ||
| val tab2 = view.findViewById<LinearLayout>(R.id.tab2) | ||
| val tab3 = view.findViewById<LinearLayout>(R.id.tab3) | ||
|
|
||
| val text1 = tab1.getChildAt(0) as TextView | ||
| val text2 = tab2.getChildAt(0) as TextView | ||
| val text3 = tab3.getChildAt(0) as TextView |
There was a problem hiding this comment.
getChildAt(0)을 사용해 직접 인덱스로 뷰를 찾는 방식은 레이아웃 구조가 조금만 바뀌어도 에러가 날 수 있어 위험해요! 가급적 ViewBinding이나 고유 ID를 부여해서 안전하게 뷰를 참조하는 걸 추천드립니다!!
There was a problem hiding this comment.
구매하기 화면내의 탭 메뉴 구성을 아주 꼼꼼하게 직접 구현하셨네요! 수고 많으셨습니다. 😊
다만, 현재 프래그먼트와 뷰 ID 이름이 Tab1Fragment, tab1처럼 일련번호 형태로 되어 있어서, 코드를 읽을 때 어떤 카테고리인지 한눈에 파악하기가 조금 어렵습니다!
Tab1Fragment → BuyAllFragment
Tab2Fragment → BuyTopsFragment
Tab3Fragment → BuyShoesFragment
이렇게 화면의 역할(카테고리명)이 드러나게 이름을 지어주면, 나중에 탭의 순서가 바뀌거나 새로운 카테고리가 추가되어도 헷갈리지 않고 훨씬 유지보수하기 편한 코드가 됩니다!
| binding.bottomBarInclude.btnHome.setOnClickListener { | ||
| replaceFragment(HomeFragment()) | ||
| } | ||
| binding.bottomBarInclude.btnBuy.setOnClickListener { | ||
| replaceFragment(BuyFragment()) | ||
| } | ||
| binding.bottomBarInclude.btnWishlist.setOnClickListener { | ||
| replaceFragment(WishlistFragment()) | ||
| } | ||
| binding.bottomBarInclude.btnShoppingcart.setOnClickListener { | ||
| replaceFragment(ShoppingcartFragment()) | ||
| } | ||
| binding.bottomBarInclude.btnProfile.setOnClickListener { | ||
| replaceFragment(ProfileFragment()) | ||
| } | ||
| } |
There was a problem hiding this comment.
바텀바를 버튼 5개로 각각 리스너를 달아 구현하셨는데, 안드로이드 표준인 BottomNavigationView와 menu.xml을 활용해 보세요! 클릭 이벤트 처리도 훨씬 간결해지고, 탭 강조 효과 같은 UI 디테일도 자동으로 해결됩니다
| private fun selectTab( | ||
| t1: TextView, | ||
| t2: TextView, | ||
| t3: TextView, | ||
| selected: TextView | ||
| ) { | ||
| t1.setTypeface(null, Typeface.NORMAL) | ||
| t2.setTypeface(null, Typeface.NORMAL) | ||
| t3.setTypeface(null, Typeface.NORMAL) | ||
|
|
||
| selected.setTypeface(null, Typeface.BOLD) | ||
| } |
There was a problem hiding this comment.
상단 탭 메뉴의 글꼴 변경 로직을 직접 함수로 만드셨는데, TabLayout을 사용하면 이런 스타일 변화나 밑줄 애니메이션을 코드 한 줄 없이 구현할 수 있어요! 뷰를 인덱스로 찾는 방식보다 훨씬 안전하고 관리하기 편해집니다
| button.setOnClickListener { | ||
| (requireActivity() as MainActivity).replaceFragment(BuyFragment()) | ||
| } |
There was a problem hiding this comment.
requireActivity() as MainActivity와 같이 특정 액티비티에 의존하는 방식은 프래그먼트의 독립성을 해칠 수 있습니다! 인터페이스를 정의하거나, 앞서 언급한 Navigation Component를 사용해 프래그먼트 간 이동을 더 유연하게 설계해 보시는 걸 추천드려요!
| fun replaceFragment(fragment: Fragment) { | ||
| supportFragmentManager.beginTransaction() | ||
| .replace(R.id.fragmentContainer, fragment) | ||
| .commit() | ||
| } |
There was a problem hiding this comment.
.replace() 방식은 호출될 때마다 기존 프래그먼트를 파괴하고 새로 생성합니다. 이 때문에 사용자가 보던 스크롤 위치나 입력 데이터가 초기화될 수 있어요. 다중 백스택을 지원하는 Navigation Component 을 쓰시는게 좋을거 같습니다!
📌 PR 제목
[feat] 2주차 미션_Nike 앱 제작
🔗 관련 이슈
Closes #15
✨ 변경 사항
🔍 테스트
📸 스크린샷 (선택)
🚨 추가 이슈