티스토리 뷰
앱개발 숙련 팀 프로젝트
구현한 기능
상단 Toolbar의 icon을 클릭했을 때 layoutManager를 사용하여
Grid/List 선택에 따라 보여주는 방식을 변경 처리하기
아이템 레이아웃
그리드 아이템은 프로필 이미지와 이름만을 세로 배치한다.
어댑터 클래스
class ArticleAdapter() :
ListAdapter<ArticleModel, RecyclerView.ViewHolder>(diffUtil) {
private fun startProfileActivity(itemView: View, articleModel: ArticleModel) {
val context = itemView.context
val intent = Intent(context, ItemProfileActivity::class.java).apply {
putExtra("name", articleModel.name)
putExtra("phoneNumber", articleModel.phoneNumber)
putExtra("email", articleModel.mail)
putExtra("profileImage", articleModel.imageUrl)
}
context.startActivity(intent)
}
inner class ListViewHolder(private val binding: ListItemArticleBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(articleModel: ArticleModel) {
binding.apply {
binding.name.text = articleModel.name
binding.profileImage.setImageResource(articleModel.imageUrl)
binding.like.setImageResource(R.drawable.heart_outlined)
binding.profileImage.setOnClickListener {
startProfileActivity(itemView, articleModel)
}
binding.like.setOnClickListener {
articleModel.dHeartCheck = !articleModel.dHeartCheck
binding.like.setImageResource(
if (articleModel.dHeartCheck) R.drawable.heart_filled
else R.drawable.heart_outlined
)
}
}
}
}
inner class GridViewHolder(private val binding: GridItemArticleBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(articleModel: ArticleModel) {
binding.apply {
binding.name.text = articleModel.name
binding.profileImage.setImageResource(articleModel.imageUrl)
binding.profileImage.setOnClickListener {
startProfileActivity(itemView, articleModel)
}
}
}
}
private var layoutId = R.layout.list_item_article
fun setLayoutId(newLayoutId: Int) {
layoutId = newLayoutId
notifyDataSetChanged()
}
override fun getItemViewType(position: Int): Int {
return if (layoutId == R.layout.list_item_article) LIST_VIEW else GRID_VIEW
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when(viewType){
LIST_VIEW->{
val binding = ListItemArticleBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
ListViewHolder(binding)
}
GRID_VIEW->{
val binding = GridItemArticleBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
GridViewHolder(binding)
}
else -> throw IllegalArgumentException("Invalid view type")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = currentList[position]
when (holder) {
is ListViewHolder -> holder.bind(item)
is GridViewHolder -> holder.bind(item)
}
}
companion object {
const val LIST_VIEW = 1
const val GRID_VIEW = 2
val diffUtil = object : DiffUtil.ItemCallback<ArticleModel>() {
override fun areItemsTheSame(oldItem: ArticleModel, newItem: ArticleModel): Boolean {
return oldItem.phoneNumber == newItem.phoneNumber
}
override fun areContentsTheSame(oldItem: ArticleModel, newItem: ArticleModel): Boolean {
return oldItem == newItem
}
}
}
}
각 아이템 레이아웃의 뷰홀더를 만들어 layoutId(아이템 레이아웃 아이디)
값에 따라 뷰타입을 초기화하도록 어댑터 클래스를 설계했다.
초기에는 리스트 형태로 아이템을 출력하도로 설정했다.
메인에서 setLayoutId를 호출하면 layoutId를 업데이트하고
notifyDataSetChanged()를 호출해 전체 아이템에 변경사항을 알린다.
드롭다운 메뉴 만들기
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_item1"
android:title="Grid Type" />
<item
android:id="@+id/action_item2"
android:title="List Type" />
</menu>
layout/menu에서 툴바의 우측 아이콘을 눌렀을 때 나오는 메뉴 레이아웃을 선언한다.
아이템 레이아웃 변경 처리
binding.ivMenu.setOnClickListener {
val popupMenu = PopupMenu(requireContext(), it)
popupMenu.menuInflater.inflate(R.menu.dropdown_menu, popupMenu.menu)
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
when (item.itemId) {
R.id.action_item1 -> {
adapter.setLayoutId(R.layout.list_item_article)
binding.articleRecyclerView.layoutManager = LinearLayoutManager(requireContext())
true
}
R.id.action_item2 -> {
adapter.setLayoutId(R.layout.grid_item_article)
binding.articleRecyclerView.layoutManager = GridLayoutManager(requireContext(), 4)
true
}
else -> false
}
}
popupMenu.show()
}
앱바의 우측 아이콘을 누르면 생성한 드롭다운 레이아웃을 기반으로
팝업메뉴를 생성하고 팝업메뉴의 itemId를 통해 아이템 선택 이벤트를 처리한다.
각 항목을 선택하면 보여줄 방식에 따라 뷰홀더와 레이아웃 매니저를 초기화한다.
번외
// 커스텀 뷰 설정
val builder = AlertDialog.Builder(requireContext())
val binding = AddContactDialogBinding.inflate(LayoutInflater.from(requireContext()))
builder.setView(binding.root)
// 다이얼로그 생성 및 표시
val dialog = builder.create()
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.show()
// 다이얼로그 크기 설정
dialog.window?.setLayout(
(requireContext().resources.displayMetrics.widthPixels * 0.9).toInt(),
LayoutParams.WRAP_CONTENT
)
다이얼로그의 너비를 조정하려면 다이얼로그의 배경색을 투명색으로
설정한 뒤 다이얼로그를 띄우고 그 후 크기를 설정하면 된다.
'내일배움캠프 > Android 국비지원' 카테고리의 다른 글
TIL 56일차 (챌린지반 6주차 세션 정리) (0) | 2024.08.08 |
---|---|
TIL 55일차 (Compose 특강 2회차 정리) (0) | 2024.08.08 |
TIL 53일차 (Compose 특강 1회차 정리) (0) | 2024.08.07 |
TIL 52일차 (챌린지반 세션 5주차 과제) (0) | 2024.08.06 |
TIL 51일차 (챌린지반 5주차 세션 정리) (0) | 2024.08.05 |