diff --git a/app/src/main/java/com/eighteen/eighteenandroid/domain/model/SearchUser.kt b/app/src/main/java/com/eighteen/eighteenandroid/domain/model/SearchUser.kt new file mode 100644 index 00000000..92ed0fef --- /dev/null +++ b/app/src/main/java/com/eighteen/eighteenandroid/domain/model/SearchUser.kt @@ -0,0 +1,8 @@ +package com.eighteen.eighteenandroid.domain.model + +data class SearchUser( + val profileImageUrl: String, + val userName: String, + val userId: String, + val likeStatus: Boolean +) diff --git a/app/src/main/java/com/eighteen/eighteenandroid/domain/model/SearchUserHistory.kt b/app/src/main/java/com/eighteen/eighteenandroid/domain/model/SearchUserHistory.kt new file mode 100644 index 00000000..c5cd4b89 --- /dev/null +++ b/app/src/main/java/com/eighteen/eighteenandroid/domain/model/SearchUserHistory.kt @@ -0,0 +1,6 @@ +package com.eighteen.eighteenandroid.domain.model + +data class SearchUserHistory( + val userName: String, + val userId: String +) diff --git a/app/src/main/java/com/eighteen/eighteenandroid/presentation/home/MainViewModel.kt b/app/src/main/java/com/eighteen/eighteenandroid/presentation/home/MainViewModel.kt index 8924b1ab..3726eeec 100644 --- a/app/src/main/java/com/eighteen/eighteenandroid/presentation/home/MainViewModel.kt +++ b/app/src/main/java/com/eighteen/eighteenandroid/presentation/home/MainViewModel.kt @@ -57,7 +57,13 @@ class MainViewModel @Inject constructor( /*fun 무한_스크롤() { val items = mainItems.value // 기존 데이터 - items.add(새로 받아온 놈들) + + if(로딩 중) { + item + 로딩 뷰 + } else { + items.add(새로 받아온 놈들) + } + _mainItems.value = items }*/ diff --git a/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchFragment.kt b/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchFragment.kt new file mode 100644 index 00000000..ef839e76 --- /dev/null +++ b/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchFragment.kt @@ -0,0 +1,68 @@ +package com.eighteen.eighteenandroid.presentation.search + +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import com.eighteen.eighteenandroid.databinding.FragmentSearchBinding +import com.eighteen.eighteenandroid.presentation.BaseFragment + +class SearchFragment : BaseFragment(FragmentSearchBinding::inflate) { + + private lateinit var searchUserAdapter: SearchUserAdapter + private lateinit var searchHistoryAdapter: SearchHistoryAdapter + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initAdapter() + } + + private fun initAdapter() { + searchUserAdapter = SearchUserAdapter( + onHeartClicked = { user -> + // 좋아요 버튼 클릭 시 + } + ) + + searchHistoryAdapter = SearchHistoryAdapter() + + bind { + rvSearchResult.adapter = searchUserAdapter + rvHistory.adapter = searchHistoryAdapter + } + } + + override fun initView() { + bind { + etInput.addTextChangedListener(object: TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, before: Int, after: Int) {} + override fun afterTextChanged(p0: Editable?) {} + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, after: Int) { + s?.let { str -> + // 입력 값이 있으면 -> 유저 검색 결과 가져오기 + if (str.isNotEmpty()) { + rvHistory.visibility = View.GONE + rvSearchResult.visibility = View.VISIBLE + + searchUserAdapter.updateList(listOf()) // TODO. 연관 검색 결과 가져오기 + + // 검색 기록 숨기기 + tvSearchHistoryHeader.visibility = View.GONE + btnDelete.visibility = View.GONE + } else { // 입력 값 없으면 -> 검색 기록 보여주기 + rvHistory.visibility = View.VISIBLE + rvSearchResult.visibility = View.GONE + + searchHistoryAdapter.updateList(listOf()) // TODO. 검색 기록 가져오기 + // 검색 기록 + tvSearchHistoryHeader.visibility = View.VISIBLE + // 검색 기록이 있으면 + btnDelete.visibility = View.VISIBLE + } + } + } + }) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchHistoryAdapter.kt b/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchHistoryAdapter.kt new file mode 100644 index 00000000..f1cda812 --- /dev/null +++ b/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchHistoryAdapter.kt @@ -0,0 +1,44 @@ +package com.eighteen.eighteenandroid.presentation.search + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.eighteen.eighteenandroid.databinding.ItemSearchHistoryBinding +import com.eighteen.eighteenandroid.domain.model.SearchUserHistory + +class SearchHistoryAdapter: ListAdapter(diffCallback) { + companion object { + val diffCallback = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: SearchUserHistory, newItem: SearchUserHistory): Boolean { + return oldItem.userId == newItem.userId + } + + override fun areContentsTheSame(oldItem: SearchUserHistory, newItem: SearchUserHistory): Boolean { + return oldItem == newItem + } + } + } + + fun updateList(newList: List) { + submitList(newList) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + val binding = ItemSearchHistoryBinding.inflate(inflater, parent, false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.onBind(getItem(position)) + } + + class ViewHolder(private val binding: ItemSearchHistoryBinding): RecyclerView.ViewHolder(binding.root) { + fun onBind(item: SearchUserHistory) { + binding.tvUserName.text = item.userName + binding.tvUserId.text = item.userId + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchUserAdapter.kt b/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchUserAdapter.kt new file mode 100644 index 00000000..18b2c129 --- /dev/null +++ b/app/src/main/java/com/eighteen/eighteenandroid/presentation/search/SearchUserAdapter.kt @@ -0,0 +1,68 @@ +package com.eighteen.eighteenandroid.presentation.search + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.eighteen.eighteenandroid.R +import com.eighteen.eighteenandroid.databinding.ItemSearchBinding +import com.eighteen.eighteenandroid.domain.model.SearchUser + +class SearchUserAdapter( + private val onHeartClicked: (SearchUser) -> Unit +): ListAdapter(diffCallback) { + companion object { + val diffCallback = object: DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: SearchUser, newItem: SearchUser): Boolean { + return oldItem.userId == newItem.userId + } + + override fun areContentsTheSame(oldItem: SearchUser, newItem: SearchUser): Boolean { + return oldItem == newItem + } + + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + val binding = ItemSearchBinding.inflate(inflater, parent, false) + return ViewHolder(binding, onHeartClicked) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.onBind(getItem(position)) + } + + fun updateList(newList: List) { + submitList(newList) + } + + class ViewHolder(private val binding: ItemSearchBinding, val onHeartClicked: (SearchUser) -> Unit): RecyclerView.ViewHolder(binding.root) { + fun onBind(item: SearchUser) { + with(binding) { + tvUserName.text = item.userName + tvUserId.text = item.userId + + // 유저 프로필 사진 + Glide.with(ivUser.context) + .load(item.profileImageUrl) + .into(ivUser) + + // 좋아요 표시 + if(item.likeStatus) { + ivHeart.setImageResource(R.drawable.ic_heart_selected) + } else { + ivHeart.setImageResource(R.drawable.ic_heart_unselected) + } + + // 좋아요 버튼 클릭 + ivHeart.setOnClickListener { + onHeartClicked(item) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_heart_selected.xml b/app/src/main/res/drawable/ic_heart_selected.xml new file mode 100644 index 00000000..faef03f3 --- /dev/null +++ b/app/src/main/res/drawable/ic_heart_selected.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_heart_unselected.xml b/app/src/main/res/drawable/ic_heart_unselected.xml new file mode 100644 index 00000000..5b901324 --- /dev/null +++ b/app/src/main/res/drawable/ic_heart_unselected.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml new file mode 100644 index 00000000..d1049de9 --- /dev/null +++ b/app/src/main/res/layout/fragment_search.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_search.xml b/app/src/main/res/layout/item_search.xml new file mode 100644 index 00000000..149a3c8f --- /dev/null +++ b/app/src/main/res/layout/item_search.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_search_history.xml b/app/src/main/res/layout/item_search_history.xml new file mode 100644 index 00000000..5c6c24a7 --- /dev/null +++ b/app/src/main/res/layout/item_search_history.xml @@ -0,0 +1,35 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fc58d578..8b9e0a28 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -193,4 +193,8 @@ 내 배지 + + + 친구를 검색해보세요 + 검색 기록 \ No newline at end of file