[TIL] 231024 회고

서정한·2023년 10월 24일
0

내일배움캠프 7기

목록 보기
62/66

Intro

  • 오늘은 사용자 프로필페이지를 만들까한다. 내 페이지와의 차이점이라면 다른 사용자의 프로필을 구경할때 본다는점일것이다.
  • 우리 앱에는 게시판기능이 들어가있다. 그래서 사실 프로필이 그렇게까지 필요한가싶기는한데 막상 넣지않기에는 좀 아쉬웠다. 왜냐하면 초기설계때부터 자기소개글을 작성하는부분이 있는데 여행에 도움이 되는 앱을 목표로 만들면서 커뮤니티 게시판을 운영하는데 거기에서 다른사람의 프로필을 볼 수 있으면 어찌되었건 사용자에게 더 좋은것 아닌가싶었다.

프로필 페이지

UI

  • UI는 특별한것은 없고 아래 작성한 글 목록에서 해당 사용자가 작성한 글을 가져오는것과 사용자의 프로필 이미지와 닉네임을 가져오는것이 전부다.
  • UI를 짜면서 딱히 어려운점은 없었고, 얼마나 실수없이 빠르게 만드는가를 보았을때에는 이전에비해 확실히 속도가 빨라진게 체감이되었다. 대략 10%정도는 빨라지지않았나싶다(느낌적인 느낌으로!?)

Initialize

  • 기능이랄건없고 화면을 정상동작하도록하는데 필요한 기능들을 붙이는 시간이었다.
  • 여기에 쓰인건 TabLayout+ViewPager2인데 왜냐하면 나중에 요구사항이 어떻게 바뀔지모르기에 지금 탭이 하나라고 TabLayout을 쓰지않았다가 나중에 바뀌면 대략 난감하기 때문에 이렇게구현했다. 그리고 ViewPager에 들어가는 Fragment에는 Recyclerview를 적용하였다. 왜냐하면 게시판 글목록이 넘어오기 때문이다.
  • 상단은 Toolbar로 구현하였다. 다른 방식도 있겠지만 Toolbar가 디자인 요구사항에도 맞고 여기에 뒤로가기 화살표 Navigation달아서 쓰는게 깔끔해서이다. 그리고 Title 뿐 아니라 다른 icon을 배치하기도 생각보다 간단해서 사용했다.
  • Recyclerview를 썼으니까 당연히 ListAdapter도 구현해줬다. 이게 오늘 내가 한 일이다 허헣..
/**
 * 작성자: 서정한
 * 내용: 사용자 프로필 Activity
 * */
class UserProfileActivity : AppCompatActivity() {
    companion object {
        const val EXTRA_MODEL = "extra_model"
        fun newIntentForGetUserProfile(context: Context, model: UserProfileModel): Intent =
            Intent(context, UserProfileActivity::class.java).apply {
                putExtra(EXTRA_MODEL, model)
            }
    }

    private val binding by lazy {
        ActivityUserProfileBinding.inflate(layoutInflater)
    }

    private val adapter by lazy{
        UserProfileTabLayoutAdapter(this@UserProfileActivity)
    }

    private val model by lazy {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
            intent.getParcelableExtra(EXTRA_MODEL, UserProfileModel::class.java)
        } else {
            intent.getParcelableExtra(EXTRA_MODEL)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        initView()
    }

    private fun initView() = with(binding) {
        userProfileViewpager.adapter = adapter
        // TabLayout x ViewPager2
        TabLayoutMediator(userProfileTablayout, userProfileViewpager) {tab, position ->
            tab.setText(adapter.getTitle(position))
        }.attach()

        // 뒤로가기
        userProfileToolbar.setNavigationOnClickListener {
            finish()
        }

        model?.let {
            // 썸네일
            userProfileThumbnail.load(it.thumbnail)
            // 닉네임
            userProfileNickname.text = it.nickname
            // 자기소개 한줄
            userProfileContentTextview.text = it.selfContent
        }
    }
}
/**
 * 작성자: 서정한
 * 내용: 해당User가 작성한 글목록을 보여주는 Fragment
 * */
class UserProfileBoardFragment : Fragment() {
    companion object{
        fun newInstance() : UserProfileBoardFragment = UserProfileBoardFragment()
    }

    private var _binding : FragmentUserProfileBoardBinding? = null
    private val binding get() = _binding!!

    private val adapter by lazy {
        UserProfileBoardListAdapter()
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentUserProfileBoardBinding.inflate(inflater, container, false)
        return binding.root
    }

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

        initView()
    }

    private fun initView()=with(binding) {
        userProfileBoardRecyclerview.adapter = adapter
    }

    override fun onDestroy() {
        _binding = null
        super.onDestroy()
    }
}
class UserProfileBoardListAdapter(

) :
    ListAdapter<UserProfileModel, UserProfileBoardListAdapter.UserProfileHolder>(
        object : DiffUtil.ItemCallback<UserProfileModel>() {
            override fun areItemsTheSame(
                oldItem: UserProfileModel,
                newItem: UserProfileModel
            ): Boolean {
                return oldItem.thumbnail == newItem.thumbnail
            }

            override fun areContentsTheSame(
                oldItem: UserProfileModel,
                newItem: UserProfileModel
            ): Boolean {
                return oldItem == newItem
            }

        }
    ) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserProfileHolder {
        val view = ItemUserProfileBoardBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return UserProfileHolder(view)
    }

    override fun onBindViewHolder(holder: UserProfileHolder, position: Int) {
        holder.bind(getItem(position))
    }

    class UserProfileHolder(private val binding: ItemUserProfileBoardBinding) :
        RecyclerView.ViewHolder(binding.root) {
            fun bind(item : UserProfileModel)=with(binding) {
                userProfileBoardUserThumbnail.load(item.thumbnail)
                userProfileBoardNickname.text = item.nickname
                userProfileBoardTitle.text = item.title
                userProfileBoardThumbnail.load(item.image)
                userProfileBoardLikes.text = item.likes
                userProfileBoardViews.text = item.views
            }

    }
}
  • 코드는 위에서 설명한것들중 핵심이라고 여겨지는것들만 적어보았다 ㅎㅎ

깎고 또 깎아야할 때

  • 이제 새로 뭔가를 만들고 기능을 구현하는것은 얼추 마무리되었다. 지금부터는 앱을 돌아보며 디테일한 부분들을 하나하나 수정해가야하는 시기인것같다.
  • 아직까지는 구현하고 점검하고 구현하고 점검하고 말고 더 좋은 방법을 잘 모르겠다..
  • 최근 1주일의 일상은 현재까지 안된사항들 한바닥 적고 그거 쳐내고 또 적고 쳐내고 하고있다! 마지막까지 잘 쳐내자!

Outro

  • 많이 배우고싶다. 당연히 지금도 많이 배우고있다. 그리고 내가 알고있다고 생각하는것들이 알고보면 잘 모르고 사용한것들이 많았다.(그중 대표적인게 requireContext, requireActivty) 이런것들도 프로젝트를 진행하고 부딪히며 배우고 알아가는 중이다.
  • 일을 진행하는 방식과 개발자들의 협업방식도 더 자세히 배우고싶다. 지금도 최선을다해 글로도 소통하려고 노력중이고 그래서 노션에 최대한 기록하려고 하고있다. 기록을 해놓으니 확실히 소통하는데 시간이 줄어들고 일에 더 집중하게되어 이부분은 큰 장점이라고 느꼈다.
  • 더 가독성좋은 코드를 보고싶다. Data와 View가 분리된 깔끔한 코드들을보며 내 코드에 가져와 적용하고싶다. 지금도 고민하며 짜는중이고, 팀원들과 소통하며 짜고있지만 확실히 더 높은 품질의 코드를 보는것이 필요한 시기가 온것같다..! 일단은 팀 프로젝트를 잘 마무리하는데 집중하고 이런모든것들은 취업하면 그곳에서 부분부분 경험할 수 있으리라 기대한다..!
profile
잘부탁드립니다!

0개의 댓글