Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.eighteen.eighteenandroid.domain.model

data class SearchUserHistory(
val userName: String,
val userId: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ class MainViewModel @Inject constructor(

/*fun 무한_스크롤() {
val items = mainItems.value // 기존 데이터
items.add(새로 받아온 놈들)

if(로딩 중) {
item + 로딩 뷰
} else {
items.add(새로 받아온 놈들)
}

_mainItems.value = items
}*/

Expand Down
Original file line number Diff line number Diff line change
@@ -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>(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
}
}
}
})
}
}
}
Original file line number Diff line number Diff line change
@@ -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<SearchUserHistory, SearchHistoryAdapter.ViewHolder>(diffCallback) {
companion object {
val diffCallback = object : DiffUtil.ItemCallback<SearchUserHistory>() {
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<SearchUserHistory>) {
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
}
}
}
Original file line number Diff line number Diff line change
@@ -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<SearchUser, SearchUserAdapter.ViewHolder>(diffCallback) {
companion object {
val diffCallback = object: DiffUtil.ItemCallback<SearchUser>() {
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<SearchUser>) {
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)
}
}
}
}
}
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_heart_selected.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M5.49,7.206C4.118,8.566 4.118,10.77 5.49,12.13L7.264,13.889L7.263,13.889L12.231,18.813L12.231,18.812L12.231,18.813L17.198,13.889L17.198,13.889L18.972,12.13C20.343,10.771 20.343,8.566 18.972,7.206C17.6,5.847 15.376,5.847 14.005,7.206L12.231,8.965L10.457,7.206C9.085,5.847 6.861,5.847 5.49,7.206Z"
android:fillColor="#000000"
android:fillType="evenOdd"/>
<path
android:pathData="M5.49,12.13L4.786,12.84H4.786L5.49,12.13ZM5.49,7.206L6.194,7.916L5.49,7.206ZM7.264,13.889L7.968,14.598L8.684,13.888L7.968,13.178L7.264,13.889ZM7.263,13.889L6.559,13.179L5.843,13.889L6.559,14.599L7.263,13.889ZM12.231,18.813L11.526,19.523L12.229,20.219L12.933,19.524L12.231,18.813ZM12.231,18.812L12.934,18.101L12.231,17.406L11.528,18.101L12.231,18.812ZM12.231,18.813L11.528,19.523L12.231,20.22L12.935,19.523L12.231,18.813ZM17.198,13.889L17.902,14.599L18.617,13.89L17.904,13.18L17.198,13.889ZM17.198,13.889L16.494,13.178L15.779,13.887L16.492,14.597L17.198,13.889ZM18.972,12.13L19.676,12.84H19.676L18.972,12.13ZM18.972,7.206L18.268,7.917L18.268,7.917L18.972,7.206ZM14.005,7.206L13.3,6.496V6.496L14.005,7.206ZM12.231,8.965L11.527,9.675L12.231,10.373L12.935,9.675L12.231,8.965ZM10.457,7.206L9.753,7.916L10.457,7.206ZM6.194,11.42C5.217,10.451 5.217,8.885 6.194,7.916L4.786,6.496C3.019,8.247 3.019,11.089 4.786,12.84L6.194,11.42ZM7.968,13.178L6.194,11.42L4.786,12.84L6.56,14.599L7.968,13.178ZM7.968,14.599L7.968,14.598L6.559,13.179L6.559,13.179L7.968,14.599ZM12.934,18.102L7.967,13.178L6.559,14.599L11.526,19.523L12.934,18.102ZM11.528,18.101L11.528,18.101L12.933,19.524L12.933,19.524L11.528,18.101ZM12.934,18.101L12.934,18.101L11.527,19.523L11.528,19.523L12.934,18.101ZM16.494,13.178L11.527,18.102L12.935,19.523L17.902,14.599L16.494,13.178ZM16.492,14.597L16.492,14.597L17.904,13.18L17.904,13.18L16.492,14.597ZM18.268,11.42L16.494,13.178L17.902,14.599L19.676,12.84L18.268,11.42ZM18.268,7.917C19.245,8.885 19.245,10.451 18.268,11.42L19.676,12.84C21.442,11.089 21.442,8.247 19.676,6.496L18.268,7.917ZM14.708,7.917C15.69,6.943 17.286,6.943 18.268,7.917L19.676,6.496C17.914,4.75 15.062,4.75 13.3,6.496L14.708,7.917ZM12.935,9.675L14.708,7.917L13.3,6.496L11.527,8.254L12.935,9.675ZM9.753,7.916L11.527,9.675L12.935,8.254L11.161,6.496L9.753,7.916ZM6.194,7.916C7.175,6.943 8.771,6.943 9.753,7.916L11.161,6.496C9.399,4.75 6.547,4.75 4.786,6.496L6.194,7.916Z"
android:fillColor="#000000"/>
</vector>
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_heart_unselected.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M5.49,7.206C4.118,8.566 4.118,10.77 5.49,12.13L7.264,13.889L7.263,13.889L12.231,18.813L12.231,18.812L12.231,18.813L17.198,13.889L17.198,13.889L18.972,12.13C20.343,10.771 20.343,8.566 18.972,7.206C17.6,5.847 15.376,5.847 14.005,7.206L12.231,8.965L10.457,7.206C9.085,5.847 6.861,5.847 5.49,7.206Z"
android:fillColor="#CFCFCF"
android:fillType="evenOdd"/>
<path
android:pathData="M5.49,12.13L4.786,12.84H4.786L5.49,12.13ZM5.49,7.206L6.194,7.916L5.49,7.206ZM7.264,13.889L7.968,14.598L8.684,13.888L7.968,13.178L7.264,13.889ZM7.263,13.889L6.559,13.179L5.843,13.889L6.559,14.599L7.263,13.889ZM12.231,18.813L11.526,19.523L12.229,20.219L12.933,19.524L12.231,18.813ZM12.231,18.812L12.934,18.101L12.231,17.406L11.528,18.101L12.231,18.812ZM12.231,18.813L11.528,19.523L12.231,20.22L12.935,19.523L12.231,18.813ZM17.198,13.889L17.902,14.599L18.617,13.89L17.904,13.18L17.198,13.889ZM17.198,13.889L16.494,13.178L15.779,13.887L16.492,14.597L17.198,13.889ZM18.972,12.13L19.676,12.84H19.676L18.972,12.13ZM18.972,7.206L18.268,7.917L18.268,7.917L18.972,7.206ZM14.005,7.206L13.3,6.496V6.496L14.005,7.206ZM12.231,8.965L11.527,9.675L12.231,10.373L12.935,9.675L12.231,8.965ZM10.457,7.206L9.753,7.916L10.457,7.206ZM6.194,11.42C5.217,10.451 5.217,8.885 6.194,7.916L4.786,6.496C3.019,8.247 3.019,11.089 4.786,12.84L6.194,11.42ZM7.968,13.178L6.194,11.42L4.786,12.84L6.56,14.599L7.968,13.178ZM7.968,14.599L7.968,14.598L6.559,13.179L6.559,13.179L7.968,14.599ZM12.934,18.102L7.967,13.178L6.559,14.599L11.526,19.523L12.934,18.102ZM11.528,18.101L11.528,18.101L12.933,19.524L12.933,19.524L11.528,18.101ZM12.934,18.101L12.934,18.101L11.527,19.523L11.528,19.523L12.934,18.101ZM16.494,13.178L11.527,18.102L12.935,19.523L17.902,14.599L16.494,13.178ZM16.492,14.597L16.492,14.597L17.904,13.18L17.904,13.18L16.492,14.597ZM18.268,11.42L16.494,13.178L17.902,14.599L19.676,12.84L18.268,11.42ZM18.268,7.917C19.245,8.885 19.245,10.451 18.268,11.42L19.676,12.84C21.442,11.089 21.442,8.247 19.676,6.496L18.268,7.917ZM14.708,7.917C15.69,6.943 17.286,6.943 18.268,7.917L19.676,6.496C17.914,4.75 15.062,4.75 13.3,6.496L14.708,7.917ZM12.935,9.675L14.708,7.917L13.3,6.496L11.527,8.254L12.935,9.675ZM9.753,7.916L11.527,9.675L12.935,8.254L11.161,6.496L9.753,7.916ZM6.194,7.916C7.175,6.943 8.771,6.943 9.753,7.916L11.161,6.496C9.399,4.75 6.547,4.75 4.786,6.496L6.194,7.916Z"
android:fillColor="#CFCFCF"/>
</vector>
126 changes: 126 additions & 0 deletions app/src/main/res/layout/fragment_search.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_height="match_parent"
tools:context=".presentation.search.SearchFragment">

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">

<ImageView
android:id="@+id/ivBtnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="16dp"
android:src="@drawable/ic_previous"
app:layout_constraintBottom_toBottomOf="@id/clInput"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/clInput"
app:tint="@color/black" />

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="@drawable/bg_rect_grey_03_r10"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/ivBtnBack"
app:layout_constraintTop_toTopOf="parent">

<EditText
android:id="@+id/etInput"
style="@style/pretendard_bold_16"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@null"
android:drawableStart="@drawable/ic_search"
android:drawablePadding="12dp"
android:drawableTint="@color/grey_01"
android:hint="@string/hint_search"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:textColor="@color/black"
android:textColorHint="@color/grey_01"
android:textCursorDrawable="@drawable/ic_text_field_cursor_grey_01"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clEmpty"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="6dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/clTop"
tools:visibility="visible">

<TextView
android:id="@+id/tvSearchHistoryHeader"
style="@style/pretendard_bold_16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_history_header"
android:textColor="@color/black"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/btnDelete"
style="@style/pretendard_regular_16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/remove"
android:textColor="@color/black"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvHistory"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:orientation="vertical"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnDelete"
tools:listitem="@layout/item_search_history" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvSearchResult"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:orientation="vertical"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnDelete"
tools:listitem="@layout/item_search"
tools:visibility="visible" />

</androidx.constraintlayout.widget.ConstraintLayout>


</androidx.constraintlayout.widget.ConstraintLayout>
Loading