feat(character): 캐릭터 탭 UI 및 기본 기능 구현
This commit is contained in:
		@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class Character(
 | 
				
			||||||
 | 
					    val id: String,
 | 
				
			||||||
 | 
					    val name: String,
 | 
				
			||||||
 | 
					    val description: String,
 | 
				
			||||||
 | 
					    val imageUrl: String,
 | 
				
			||||||
 | 
					    val ranking: Int? = null // 인기 캐릭터에서만 사용
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.view.LayoutInflater
 | 
				
			||||||
 | 
					import android.view.View
 | 
				
			||||||
 | 
					import android.view.ViewGroup
 | 
				
			||||||
 | 
					import android.widget.ImageView
 | 
				
			||||||
 | 
					import android.widget.LinearLayout
 | 
				
			||||||
 | 
					import android.widget.TextView
 | 
				
			||||||
 | 
					import androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.R
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.Character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CharacterAdapter(
 | 
				
			||||||
 | 
					    private var characters: List<Character> = emptyList(),
 | 
				
			||||||
 | 
					    private val showRanking: Boolean = false,
 | 
				
			||||||
 | 
					    private val onCharacterClick: (Character) -> Unit = {}
 | 
				
			||||||
 | 
					) : RecyclerView.Adapter<CharacterAdapter.ViewHolder>() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
 | 
				
			||||||
 | 
					        val ivCharacter: ImageView = itemView.findViewById(R.id.iv_character)
 | 
				
			||||||
 | 
					        val tvCharacterName: TextView = itemView.findViewById(R.id.tv_character_name)
 | 
				
			||||||
 | 
					        val tvCharacterDescription: TextView = itemView.findViewById(R.id.tv_character_description)
 | 
				
			||||||
 | 
					        val llRanking: LinearLayout = itemView.findViewById(R.id.ll_ranking)
 | 
				
			||||||
 | 
					        val tvRanking: TextView = itemView.findViewById(R.id.tv_ranking)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
 | 
				
			||||||
 | 
					        val view = LayoutInflater.from(parent.context)
 | 
				
			||||||
 | 
					            .inflate(R.layout.item_character, parent, false)
 | 
				
			||||||
 | 
					        return ViewHolder(view)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
 | 
				
			||||||
 | 
					        val character = characters[position]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        holder.tvCharacterName.text = character.name
 | 
				
			||||||
 | 
					        holder.tvCharacterDescription.text = character.description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 순위 표시 여부 결정
 | 
				
			||||||
 | 
					        if (showRanking && character.ranking != null) {
 | 
				
			||||||
 | 
					            holder.llRanking.visibility = View.VISIBLE
 | 
				
			||||||
 | 
					            holder.tvRanking.text = character.ranking.toString()
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            holder.llRanking.visibility = View.GONE
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: 이미지 로딩 라이브러리 사용 (Glide, Picasso 등)
 | 
				
			||||||
 | 
					        // Glide.with(holder.itemView.context)
 | 
				
			||||||
 | 
					        //     .load(character.imageUrl)
 | 
				
			||||||
 | 
					        //     .into(holder.ivCharacter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        holder.itemView.setOnClickListener {
 | 
				
			||||||
 | 
					            onCharacterClick(character)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun getItemCount(): Int = characters.size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun updateCharacters(newCharacters: List<Character>) {
 | 
				
			||||||
 | 
					        characters = newCharacters
 | 
				
			||||||
 | 
					        notifyDataSetChanged()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,15 +2,162 @@ package kr.co.vividnext.sodalive.chat.character
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import android.os.Bundle
 | 
					import android.os.Bundle
 | 
				
			||||||
import android.view.View
 | 
					import android.view.View
 | 
				
			||||||
 | 
					import androidx.recyclerview.widget.LinearLayoutManager
 | 
				
			||||||
import kr.co.vividnext.sodalive.base.BaseFragment
 | 
					import kr.co.vividnext.sodalive.base.BaseFragment
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.curation.CurationSection
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.curation.CurationSectionAdapter
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.recent.RecentCharacter
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.recent.RecentCharacterAdapter
 | 
				
			||||||
import kr.co.vividnext.sodalive.databinding.FragmentCharacterTabBinding
 | 
					import kr.co.vividnext.sodalive.databinding.FragmentCharacterTabBinding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 캐릭터 탭 프래그먼트
 | 
					// 캐릭터 탭 프래그먼트
 | 
				
			||||||
class CharacterTabFragment : BaseFragment<FragmentCharacterTabBinding>(
 | 
					class CharacterTabFragment : BaseFragment<FragmentCharacterTabBinding>(
 | 
				
			||||||
    FragmentCharacterTabBinding::inflate
 | 
					    FragmentCharacterTabBinding::inflate
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private lateinit var recentCharacterAdapter: RecentCharacterAdapter
 | 
				
			||||||
 | 
					    private lateinit var popularCharacterAdapter: CharacterAdapter
 | 
				
			||||||
 | 
					    private lateinit var newCharacterAdapter: CharacterAdapter
 | 
				
			||||||
 | 
					    private lateinit var curationSectionAdapter: CurationSectionAdapter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
 | 
					    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
 | 
				
			||||||
        super.onViewCreated(view, savedInstanceState)
 | 
					        super.onViewCreated(view, savedInstanceState)
 | 
				
			||||||
        // 캐릭터 탭 초기화 로직
 | 
					        setupRecyclerViews()
 | 
				
			||||||
 | 
					        loadData()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun setupRecyclerViews() {
 | 
				
			||||||
 | 
					        // 최근 대화한 캐릭터 RecyclerView 설정
 | 
				
			||||||
 | 
					        recentCharacterAdapter = RecentCharacterAdapter { character ->
 | 
				
			||||||
 | 
					            // 캐릭터 클릭 처리
 | 
				
			||||||
 | 
					            onRecentCharacterClick(character)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        binding.rvRecentCharacters.apply {
 | 
				
			||||||
 | 
					            layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
 | 
				
			||||||
 | 
					            adapter = recentCharacterAdapter
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 인기 캐릭터 RecyclerView 설정 (순위 표시)
 | 
				
			||||||
 | 
					        popularCharacterAdapter = CharacterAdapter(
 | 
				
			||||||
 | 
					            showRanking = true
 | 
				
			||||||
 | 
					        ) { character ->
 | 
				
			||||||
 | 
					            // 캐릭터 클릭 처리
 | 
				
			||||||
 | 
					            onCharacterClick(character)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        binding.rvPopularCharacters.apply {
 | 
				
			||||||
 | 
					            layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
 | 
				
			||||||
 | 
					            adapter = popularCharacterAdapter
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 신규 캐릭터 RecyclerView 설정
 | 
				
			||||||
 | 
					        newCharacterAdapter = CharacterAdapter(
 | 
				
			||||||
 | 
					            showRanking = false
 | 
				
			||||||
 | 
					        ) { character ->
 | 
				
			||||||
 | 
					            // 캐릭터 클릭 처리
 | 
				
			||||||
 | 
					            onCharacterClick(character)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        binding.rvNewCharacters.apply {
 | 
				
			||||||
 | 
					            layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
 | 
				
			||||||
 | 
					            adapter = newCharacterAdapter
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 큐레이션 섹션 RecyclerView 설정
 | 
				
			||||||
 | 
					        curationSectionAdapter = CurationSectionAdapter { character ->
 | 
				
			||||||
 | 
					            // 캐릭터 클릭 처리
 | 
				
			||||||
 | 
					            onCharacterClick(character)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        binding.rvCurationSections.apply {
 | 
				
			||||||
 | 
					            layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
 | 
				
			||||||
 | 
					            adapter = curationSectionAdapter
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 전체보기 버튼 클릭 리스너
 | 
				
			||||||
 | 
					        binding.tvFamousCharacterAll.setOnClickListener {
 | 
				
			||||||
 | 
					            // 인기 캐릭터 전체보기 처리
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        binding.tvNewCharacterAll.setOnClickListener {
 | 
				
			||||||
 | 
					            // 신규 캐릭터 전체보기 처리
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun loadData() {
 | 
				
			||||||
 | 
					        // TODO: 실제 데이터 로딩 로직 구현
 | 
				
			||||||
 | 
					        loadRecentCharacters()
 | 
				
			||||||
 | 
					        loadPopularCharacters()
 | 
				
			||||||
 | 
					        loadNewCharacters()
 | 
				
			||||||
 | 
					        loadCurationSections()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun loadRecentCharacters() {
 | 
				
			||||||
 | 
					        // TODO: 서버에서 최근 대화한 캐릭터 데이터 로드
 | 
				
			||||||
 | 
					        val recentCharacters = listOf(
 | 
				
			||||||
 | 
					            RecentCharacter("1", "Yubin...", ""),
 | 
				
			||||||
 | 
					            RecentCharacter("2", "Yubin...", ""),
 | 
				
			||||||
 | 
					            RecentCharacter("3", "Yubin...", ""),
 | 
				
			||||||
 | 
					            RecentCharacter("4", "Yubin...", ""),
 | 
				
			||||||
 | 
					            RecentCharacter("5", "Yubin...", "")
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        recentCharacterAdapter.updateCharacters(recentCharacters)
 | 
				
			||||||
 | 
					        binding.tvLatestCharacterCount.text = recentCharacters.size.toString()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun loadPopularCharacters() {
 | 
				
			||||||
 | 
					        // TODO: 서버에서 인기 캐릭터 데이터 로드
 | 
				
			||||||
 | 
					        val popularCharacters = listOf(
 | 
				
			||||||
 | 
					            Character("1", "캐릭터 이름", "캐릭터 한줄 소개인데 2줄까", "", 1),
 | 
				
			||||||
 | 
					            Character("2", "캐릭터 이름", "캐릭터 한줄 소개인데 2줄까", "", 2),
 | 
				
			||||||
 | 
					            Character("3", "캐릭터 이름", "#태그#태그#태그", "", 3),
 | 
				
			||||||
 | 
					            Character("4", "캐릭터 이름", "캐릭터 한줄 소개인데 2줄까", "", 4),
 | 
				
			||||||
 | 
					            Character("5", "캐릭터 이름", "캐릭터 한줄 소개인데 2줄까", "", 5)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        popularCharacterAdapter.updateCharacters(popularCharacters)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun loadNewCharacters() {
 | 
				
			||||||
 | 
					        // TODO: 서버에서 신규 캐릭터 데이터 로드
 | 
				
			||||||
 | 
					        val newCharacters = listOf(
 | 
				
			||||||
 | 
					            Character("1", "캐릭터 이름", "캐릭터 한줄 소개인데 2줄까", ""),
 | 
				
			||||||
 | 
					            Character("2", "하이퍼나이프", "캐릭터 한줄 소개인데 2줄까", ""),
 | 
				
			||||||
 | 
					            Character("3", "내일", "#태그#태그", "")
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        newCharacterAdapter.updateCharacters(newCharacters)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun loadCurationSections() {
 | 
				
			||||||
 | 
					        // TODO: 서버에서 큐레이션 섹션 데이터 로드
 | 
				
			||||||
 | 
					        val curationSections = listOf(
 | 
				
			||||||
 | 
					            CurationSection(
 | 
				
			||||||
 | 
					                "1",
 | 
				
			||||||
 | 
					                "큐레이션",
 | 
				
			||||||
 | 
					                listOf(
 | 
				
			||||||
 | 
					                    Character("1", "캐릭터 이름", "캐릭터 한줄 소개인데 2줄까", ""),
 | 
				
			||||||
 | 
					                    Character("2", "하이퍼나이프", "캐릭터 한줄 소개인데 2줄까", ""),
 | 
				
			||||||
 | 
					                    Character("3", "내일", "#태그#태그", "")
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            CurationSection(
 | 
				
			||||||
 | 
					                "2",
 | 
				
			||||||
 | 
					                "큐레이션",
 | 
				
			||||||
 | 
					                listOf(
 | 
				
			||||||
 | 
					                    Character("4", "캐릭터 이름", "캐릭터 한줄 소개인데 2줄까", ""),
 | 
				
			||||||
 | 
					                    Character("5", "하이퍼나이프", "캐릭터 한줄 소개인데 2줄까", ""),
 | 
				
			||||||
 | 
					                    Character("6", "내일", "#태그#태그", "")
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        curationSectionAdapter.updateSections(curationSections)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun onRecentCharacterClick(character: RecentCharacter) {
 | 
				
			||||||
 | 
					        // TODO: 최근 대화한 캐릭터 클릭 처리
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun onCharacterClick(character: Character) {
 | 
				
			||||||
 | 
					        // TODO: 캐릭터 클릭 처리
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character.curation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.Character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class CurationSection(
 | 
				
			||||||
 | 
					    val id: String,
 | 
				
			||||||
 | 
					    val title: String,
 | 
				
			||||||
 | 
					    val characters: List<Character>
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character.curation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.view.LayoutInflater
 | 
				
			||||||
 | 
					import android.view.View
 | 
				
			||||||
 | 
					import android.view.ViewGroup
 | 
				
			||||||
 | 
					import android.widget.TextView
 | 
				
			||||||
 | 
					import androidx.recyclerview.widget.LinearLayoutManager
 | 
				
			||||||
 | 
					import androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.R
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.CharacterAdapter
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.Character
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.curation.CurationSection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CurationSectionAdapter(
 | 
				
			||||||
 | 
					    private var sections: List<CurationSection> = emptyList(),
 | 
				
			||||||
 | 
					    private val onCharacterClick: (Character) -> Unit = {}
 | 
				
			||||||
 | 
					) : RecyclerView.Adapter<CurationSectionAdapter.ViewHolder>() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
 | 
				
			||||||
 | 
					        val tvSectionTitle: TextView = itemView.findViewById(R.id.tv_section_title)
 | 
				
			||||||
 | 
					        val rvCharacters: RecyclerView = itemView.findViewById(R.id.rv_characters)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
 | 
				
			||||||
 | 
					        val view = LayoutInflater.from(parent.context)
 | 
				
			||||||
 | 
					            .inflate(R.layout.item_curation_section, parent, false)
 | 
				
			||||||
 | 
					        return ViewHolder(view)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
 | 
				
			||||||
 | 
					        val section = sections[position]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        holder.tvSectionTitle.text = section.title
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 캐릭터 리스트 설정
 | 
				
			||||||
 | 
					        val characterAdapter = CharacterAdapter(
 | 
				
			||||||
 | 
					            characters = section.characters,
 | 
				
			||||||
 | 
					            showRanking = false,
 | 
				
			||||||
 | 
					            onCharacterClick = onCharacterClick
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        holder.rvCharacters.apply {
 | 
				
			||||||
 | 
					            layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
 | 
				
			||||||
 | 
					            adapter = characterAdapter
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun getItemCount(): Int = sections.size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun updateSections(newSections: List<CurationSection>) {
 | 
				
			||||||
 | 
					        sections = newSections
 | 
				
			||||||
 | 
					        notifyDataSetChanged()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character.recent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class RecentCharacter(
 | 
				
			||||||
 | 
					    val id: String,
 | 
				
			||||||
 | 
					    val name: String,
 | 
				
			||||||
 | 
					    val profileImageUrl: String
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character.recent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.annotation.SuppressLint
 | 
				
			||||||
 | 
					import android.view.LayoutInflater
 | 
				
			||||||
 | 
					import android.view.View
 | 
				
			||||||
 | 
					import android.view.ViewGroup
 | 
				
			||||||
 | 
					import android.widget.ImageView
 | 
				
			||||||
 | 
					import android.widget.TextView
 | 
				
			||||||
 | 
					import androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.R
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RecentCharacterAdapter(
 | 
				
			||||||
 | 
					    private var characters: List<RecentCharacter> = emptyList(),
 | 
				
			||||||
 | 
					    private val onCharacterClick: (RecentCharacter) -> Unit = {}
 | 
				
			||||||
 | 
					) : RecyclerView.Adapter<RecentCharacterAdapter.ViewHolder>() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
 | 
				
			||||||
 | 
					        val ivProfile: ImageView = itemView.findViewById(R.id.iv_profile)
 | 
				
			||||||
 | 
					        val tvName: TextView = itemView.findViewById(R.id.tv_name)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
 | 
				
			||||||
 | 
					        val view = LayoutInflater.from(parent.context)
 | 
				
			||||||
 | 
					            .inflate(R.layout.item_recent_character, parent, false)
 | 
				
			||||||
 | 
					        return ViewHolder(view)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
 | 
				
			||||||
 | 
					        val character = characters[position]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        holder.tvName.text = character.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: 이미지 로딩 라이브러리 사용 (Glide, Picasso 등)
 | 
				
			||||||
 | 
					        // Glide.with(holder.itemView.context)
 | 
				
			||||||
 | 
					        //     .load(character.profileImageUrl)
 | 
				
			||||||
 | 
					        //     .into(holder.ivProfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        holder.itemView.setOnClickListener {
 | 
				
			||||||
 | 
					            onCharacterClick(character)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun getItemCount(): Int = characters.size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressLint("NotifyDataSetChanged")
 | 
				
			||||||
 | 
					    fun updateCharacters(newCharacters: List<RecentCharacter>) {
 | 
				
			||||||
 | 
					        characters = newCharacters
 | 
				
			||||||
 | 
					        notifyDataSetChanged()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								app/src/main/res/drawable/gradient_ranking_bg.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/src/main/res/drawable/gradient_ranking_bg.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<shape xmlns:android="http://schemas.android.com/apk/res/android">
 | 
				
			||||||
 | 
					    <gradient
 | 
				
			||||||
 | 
					        android:angle="135"
 | 
				
			||||||
 | 
					        android:startColor="#80000000"
 | 
				
			||||||
 | 
					        android:centerColor="#99000000"
 | 
				
			||||||
 | 
					        android:endColor="#CC000000"
 | 
				
			||||||
 | 
					        android:type="linear" />
 | 
				
			||||||
 | 
					    <corners
 | 
				
			||||||
 | 
					        android:bottomLeftRadius="16dp"
 | 
				
			||||||
 | 
					        android:bottomRightRadius="0dp"
 | 
				
			||||||
 | 
					        android:topLeftRadius="0dp"
 | 
				
			||||||
 | 
					        android:topRightRadius="0dp" />
 | 
				
			||||||
 | 
					</shape>
 | 
				
			||||||
@@ -1,19 +1,183 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
					<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
					    xmlns:tools="http://schemas.android.com/tools"
 | 
				
			||||||
    android:layout_width="match_parent"
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
    android:layout_height="match_parent"
 | 
					    android:layout_height="match_parent"
 | 
				
			||||||
    android:background="@color/black">
 | 
					    android:background="@color/color_131313"
 | 
				
			||||||
 | 
					    android:fillViewport="true">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <TextView
 | 
					    <LinearLayout
 | 
				
			||||||
        android:layout_width="wrap_content"
 | 
					        android:layout_width="match_parent"
 | 
				
			||||||
        android:layout_height="wrap_content"
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
        android:text="캐릭터 탭"
 | 
					        android:orientation="vertical">
 | 
				
			||||||
        android:textColor="@color/white"
 | 
					 | 
				
			||||||
        android:textSize="20sp"
 | 
					 | 
				
			||||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
					 | 
				
			||||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
					 | 
				
			||||||
        app:layout_constraintStart_toStartOf="parent"
 | 
					 | 
				
			||||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
					        <!-- 배너 섹션 -->
 | 
				
			||||||
 | 
					        <LinearLayout
 | 
				
			||||||
 | 
					            android:id="@+id/ll_banner"
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_marginBottom="48dp"
 | 
				
			||||||
 | 
					            android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <com.zhpan.bannerview.BannerViewPager
 | 
				
			||||||
 | 
					                android:id="@+id/event_banner_slider"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:clipChildren="false"
 | 
				
			||||||
 | 
					                android:clipToPadding="false" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <com.zhpan.indicator.IndicatorView
 | 
				
			||||||
 | 
					                android:id="@+id/indicator_event_banner"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_gravity="center"
 | 
				
			||||||
 | 
					                android:layout_marginTop="28dp" />
 | 
				
			||||||
 | 
					        </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 최근 대화한 캐릭터 섹션 -->
 | 
				
			||||||
 | 
					        <LinearLayout
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_marginBottom="48dp"
 | 
				
			||||||
 | 
					            android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- 제목 -->
 | 
				
			||||||
 | 
					            <LinearLayout
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:gravity="center_vertical"
 | 
				
			||||||
 | 
					                android:orientation="horizontal"
 | 
				
			||||||
 | 
					                android:paddingHorizontal="24dp">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <TextView
 | 
				
			||||||
 | 
					                    android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:fontFamily="@font/pretendard_bold"
 | 
				
			||||||
 | 
					                    android:text="최근 대화한 캐릭터"
 | 
				
			||||||
 | 
					                    android:textColor="@color/white"
 | 
				
			||||||
 | 
					                    android:textSize="20sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <TextView
 | 
				
			||||||
 | 
					                    android:id="@+id/tv_latest_character_count"
 | 
				
			||||||
 | 
					                    android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_marginStart="6dp"
 | 
				
			||||||
 | 
					                    android:fontFamily="@font/pretendard_bold"
 | 
				
			||||||
 | 
					                    android:textColor="@color/color_fdca2f"
 | 
				
			||||||
 | 
					                    android:textSize="20sp"
 | 
				
			||||||
 | 
					                    tools:text="14" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- 프로필 리스트 -->
 | 
				
			||||||
 | 
					            <androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					                android:id="@+id/rv_recent_characters"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_marginTop="16dp"
 | 
				
			||||||
 | 
					                android:clipToPadding="false"
 | 
				
			||||||
 | 
					                android:paddingHorizontal="24dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 인기 캐릭터 섹션 -->
 | 
				
			||||||
 | 
					        <LinearLayout
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_marginBottom="48dp"
 | 
				
			||||||
 | 
					            android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- 제목과 전체보기 -->
 | 
				
			||||||
 | 
					            <LinearLayout
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:gravity="center_vertical"
 | 
				
			||||||
 | 
					                android:orientation="horizontal"
 | 
				
			||||||
 | 
					                android:paddingHorizontal="24dp">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <TextView
 | 
				
			||||||
 | 
					                    android:layout_width="0dp"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_weight="1"
 | 
				
			||||||
 | 
					                    android:fontFamily="@font/pretendard_bold"
 | 
				
			||||||
 | 
					                    android:text="인기 캐릭터"
 | 
				
			||||||
 | 
					                    android:textColor="@color/white"
 | 
				
			||||||
 | 
					                    android:textSize="24sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <TextView
 | 
				
			||||||
 | 
					                    android:id="@+id/tv_famous_character_all"
 | 
				
			||||||
 | 
					                    android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:fontFamily="@font/pretendard_regular"
 | 
				
			||||||
 | 
					                    android:text="전체보기"
 | 
				
			||||||
 | 
					                    android:textColor="#90A4AE"
 | 
				
			||||||
 | 
					                    android:textSize="14sp" />
 | 
				
			||||||
 | 
					            </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- 캐릭터 카드 리스트 -->
 | 
				
			||||||
 | 
					            <androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					                android:id="@+id/rv_popular_characters"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_marginTop="16dp"
 | 
				
			||||||
 | 
					                android:clipToPadding="false"
 | 
				
			||||||
 | 
					                android:paddingStart="24dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 신규 캐릭터 섹션 -->
 | 
				
			||||||
 | 
					        <LinearLayout
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_marginBottom="48dp"
 | 
				
			||||||
 | 
					            android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- 제목과 전체보기 -->
 | 
				
			||||||
 | 
					            <LinearLayout
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:gravity="center_vertical"
 | 
				
			||||||
 | 
					                android:orientation="horizontal"
 | 
				
			||||||
 | 
					                android:paddingHorizontal="24dp">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <TextView
 | 
				
			||||||
 | 
					                    android:layout_width="0dp"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_weight="1"
 | 
				
			||||||
 | 
					                    android:fontFamily="@font/pretendard_bold"
 | 
				
			||||||
 | 
					                    android:text="신규 캐릭터"
 | 
				
			||||||
 | 
					                    android:textColor="@color/white"
 | 
				
			||||||
 | 
					                    android:textSize="24sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <TextView
 | 
				
			||||||
 | 
					                    android:id="@+id/tv_new_character_all"
 | 
				
			||||||
 | 
					                    android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:fontFamily="@font/pretendard_regular"
 | 
				
			||||||
 | 
					                    android:text="전체보기"
 | 
				
			||||||
 | 
					                    android:textColor="#90A4AE"
 | 
				
			||||||
 | 
					                    android:textSize="14sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- 캐릭터 카드 리스트 -->
 | 
				
			||||||
 | 
					            <androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					                android:id="@+id/rv_new_characters"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_marginTop="16dp"
 | 
				
			||||||
 | 
					                android:clipToPadding="false"
 | 
				
			||||||
 | 
					                android:paddingStart="24dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 큐레이션 섹션들 -->
 | 
				
			||||||
 | 
					        <androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					            android:id="@+id/rv_curation_sections"
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_marginBottom="24dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</androidx.core.widget.NestedScrollView>
 | 
				
			||||||
							
								
								
									
										71
									
								
								app/src/main/res/layout/item_character.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								app/src/main/res/layout/item_character.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    android:layout_width="168dp"
 | 
				
			||||||
 | 
					    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					    android:layout_marginEnd="16dp">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <LinearLayout
 | 
				
			||||||
 | 
					        android:layout_width="match_parent"
 | 
				
			||||||
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					        android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <ImageView
 | 
				
			||||||
 | 
					            android:id="@+id/iv_character"
 | 
				
			||||||
 | 
					            android:layout_width="168dp"
 | 
				
			||||||
 | 
					            android:layout_height="168dp"
 | 
				
			||||||
 | 
					            android:background="@color/color_777777"
 | 
				
			||||||
 | 
					            android:scaleType="centerCrop" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <LinearLayout
 | 
				
			||||||
 | 
					            android:layout_width="match_parent"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_marginStart="6dp"
 | 
				
			||||||
 | 
					            android:layout_marginTop="4dp"
 | 
				
			||||||
 | 
					            android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:id="@+id/tv_character_name"
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:fontFamily="@font/pretendard_regular"
 | 
				
			||||||
 | 
					                android:textColor="@color/color_b0bec5"
 | 
				
			||||||
 | 
					                android:textSize="18sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:id="@+id/tv_character_description"
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_marginStart="6dp"
 | 
				
			||||||
 | 
					                android:layout_marginTop="4dp"
 | 
				
			||||||
 | 
					                android:fontFamily="@font/pretendard_regular"
 | 
				
			||||||
 | 
					                android:textColor="#78909C"
 | 
				
			||||||
 | 
					                android:textSize="14sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- 순위 표시 (인기 캐릭터에서만 보임) -->
 | 
				
			||||||
 | 
					    <LinearLayout
 | 
				
			||||||
 | 
					        android:id="@+id/ll_ranking"
 | 
				
			||||||
 | 
					        android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					        android:layout_gravity="bottom"
 | 
				
			||||||
 | 
					        android:background="@drawable/gradient_ranking_bg"
 | 
				
			||||||
 | 
					        android:gravity="center"
 | 
				
			||||||
 | 
					        android:orientation="horizontal"
 | 
				
			||||||
 | 
					        android:paddingHorizontal="16dp"
 | 
				
			||||||
 | 
					        android:paddingVertical="8dp"
 | 
				
			||||||
 | 
					        android:visibility="gone">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <TextView
 | 
				
			||||||
 | 
					            android:id="@+id/tv_ranking"
 | 
				
			||||||
 | 
					            android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:fontFamily="@font/pretendard_bold"
 | 
				
			||||||
 | 
					            android:textColor="@color/white"
 | 
				
			||||||
 | 
					            android:textSize="72sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</FrameLayout>
 | 
				
			||||||
							
								
								
									
										36
									
								
								app/src/main/res/layout/item_curation_section.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/src/main/res/layout/item_curation_section.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
 | 
					    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					    android:layout_marginBottom="48dp"
 | 
				
			||||||
 | 
					    android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- 제목 -->
 | 
				
			||||||
 | 
					    <LinearLayout
 | 
				
			||||||
 | 
					        android:layout_width="match_parent"
 | 
				
			||||||
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					        android:gravity="center_vertical"
 | 
				
			||||||
 | 
					        android:orientation="horizontal"
 | 
				
			||||||
 | 
					        android:paddingHorizontal="24dp">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <TextView
 | 
				
			||||||
 | 
					            android:id="@+id/tv_section_title"
 | 
				
			||||||
 | 
					            android:layout_width="0dp"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_weight="1"
 | 
				
			||||||
 | 
					            android:fontFamily="@font/pretendard_bold"
 | 
				
			||||||
 | 
					            android:textColor="@color/white"
 | 
				
			||||||
 | 
					            android:textSize="24sp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- 캐릭터 카드 리스트 -->
 | 
				
			||||||
 | 
					    <androidx.recyclerview.widget.RecyclerView
 | 
				
			||||||
 | 
					        android:id="@+id/rv_characters"
 | 
				
			||||||
 | 
					        android:layout_width="match_parent"
 | 
				
			||||||
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					        android:layout_marginTop="16dp"
 | 
				
			||||||
 | 
					        android:clipToPadding="false"
 | 
				
			||||||
 | 
					        android:paddingStart="24dp" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</LinearLayout>
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/src/main/res/layout/item_recent_character.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/src/main/res/layout/item_recent_character.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    android:layout_width="76dp"
 | 
				
			||||||
 | 
					    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					    android:gravity="center"
 | 
				
			||||||
 | 
					    android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ImageView
 | 
				
			||||||
 | 
					        android:id="@+id/iv_profile"
 | 
				
			||||||
 | 
					        android:layout_width="76dp"
 | 
				
			||||||
 | 
					        android:layout_height="76dp"
 | 
				
			||||||
 | 
					        android:background="@color/color_777777"
 | 
				
			||||||
 | 
					        android:contentDescription="@null"
 | 
				
			||||||
 | 
					        android:scaleType="centerCrop" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <TextView
 | 
				
			||||||
 | 
					        android:id="@+id/tv_name"
 | 
				
			||||||
 | 
					        android:layout_width="match_parent"
 | 
				
			||||||
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					        android:layout_marginTop="6dp"
 | 
				
			||||||
 | 
					        android:ellipsize="end"
 | 
				
			||||||
 | 
					        android:fontFamily="@font/pretendard_regular"
 | 
				
			||||||
 | 
					        android:gravity="center"
 | 
				
			||||||
 | 
					        android:maxLines="1"
 | 
				
			||||||
 | 
					        android:textColor="@color/white"
 | 
				
			||||||
 | 
					        android:textSize="18sp" />
 | 
				
			||||||
 | 
					</LinearLayout>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user