From a7381d7fa21324e1b8f304d0f8dabbe7afd5ae4a Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Tue, 2 Apr 2024 20:50:57 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat=20:=20=EA=B2=80=EC=83=89=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EC=97=86=EC=9D=84=20=EB=95=8C=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/view/search/SearchFragment.kt | 9 ++++ .../ui/view/search/SearchViewModel.kt | 4 ++ app/src/main/res/drawable/ic_search_empty.xml | 9 ++++ app/src/main/res/layout/fragment_search.xml | 43 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 5 files changed, 67 insertions(+) create mode 100644 app/src/main/res/drawable/ic_search_empty.xml diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt index f21aba5f..16abf718 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt @@ -50,6 +50,14 @@ class SearchFragment : BaseFragment() { viewModel.errorState.observe(viewLifecycleOwner, EventObserver { resId -> showToast(getString(resId)) }) + + viewModel.noSearchResult.observe(viewLifecycleOwner) { noSearchResult -> + if (noSearchResult) { + binding.clSearchEmpty.visibility = View.VISIBLE + } else { + binding.clSearchEmpty.visibility = View.GONE + } + } } override fun initAfterBinding() = Unit @@ -110,6 +118,7 @@ class SearchFragment : BaseFragment() { binding.etSearchBar.setOnEditorActionListener { v, actionId, event -> if (actionId == EditorInfo.IME_ACTION_SEARCH) { viewModel.fetchSearchNotices() + adapter.submitList(emptyList()) requireContext().hideKeyboard(binding.root) true } else { diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt index 219ba829..665a320d 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt @@ -32,6 +32,9 @@ class SearchViewModel( private val _myDepartment: MutableLiveData = MutableLiveData() val myDepartment: LiveData = _myDepartment + private val _noSearchResult: MutableLiveData = MutableLiveData(false) + val noSearchResult: LiveData = _noSearchResult + private val _searchNotices: MutableLiveData> = MutableLiveData() val searchNotices: LiveData> = _searchNotices @@ -72,6 +75,7 @@ class SearchViewModel( )) { is NetworkResult.Success -> { val updatedSearchResult = _searchNotices.value.orEmpty() + result.data + _noSearchResult.value = updatedSearchResult.isEmpty() _searchNotices.postValue(updatedSearchResult) _isError.postValue(false) _isLoading.postValue(false) diff --git a/app/src/main/res/drawable/ic_search_empty.xml b/app/src/main/res/drawable/ic_search_empty.xml new file mode 100644 index 00000000..0858fea0 --- /dev/null +++ b/app/src/main/res/drawable/ic_search_empty.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index e0934ebb..2b2c9cec 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -74,5 +74,48 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/cl_search_bar" tools:listitem="@layout/item_notice" /> + + + + + + + + + \ 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 608f8ae9..40eb212a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -132,4 +132,6 @@ 검색어를 입력하세요. + 검색 결과를 찾을 수 없어요 + 다른 키워드로 검색해보세요. \ No newline at end of file From ae0a7b50916f779e5a45d25443d4b62890f09373 Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Tue, 2 Apr 2024 21:17:15 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat=20:=20=EA=B2=80=EC=83=89=202=EA=B8=80?= =?UTF-8?q?=EC=9E=90=20=EC=9D=B4=EC=83=81=EC=9C=BC=EB=A1=9C=20=EC=A0=9C?= =?UTF-8?q?=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/view/search/SearchFragment.kt | 18 ++++++++++++++++-- .../ui/view/search/SearchViewModel.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt index 16abf718..75a4fb3b 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt @@ -24,6 +24,7 @@ class SearchFragment : BaseFragment() { override val viewModel: SearchViewModel by viewModel() private lateinit var adapter: NoticeAdapter + private var searchContent: String = "" override fun initStartView() { setupRecyclerview() @@ -47,6 +48,10 @@ class SearchFragment : BaseFragment() { } } + viewModel.searchContent.observe(viewLifecycleOwner) { content -> + searchContent = content + } + viewModel.errorState.observe(viewLifecycleOwner, EventObserver { resId -> showToast(getString(resId)) }) @@ -117,8 +122,13 @@ class SearchFragment : BaseFragment() { private fun onSearchBtnClickListener() { binding.etSearchBar.setOnEditorActionListener { v, actionId, event -> if (actionId == EditorInfo.IME_ACTION_SEARCH) { - viewModel.fetchSearchNotices() - adapter.submitList(emptyList()) + if (validateSearchContentLength()) { + viewModel.fetchSearchNotices() + adapter.submitList(emptyList()) + } else { + binding.etSearchBar.text.clear() + showToast(getString(R.string.search_minimum)) + } requireContext().hideKeyboard(binding.root) true } else { @@ -127,6 +137,10 @@ class SearchFragment : BaseFragment() { } } + private fun validateSearchContentLength(): Boolean { + return searchContent.length >= 2 + } + private fun navigateToDetail(url: String) { val intent = DetailActivity.newIntent(requireContext(), url) startActivity(intent) diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt index 665a320d..7c6e6f67 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchViewModel.kt @@ -24,7 +24,7 @@ class SearchViewModel( val isError: LiveData = _isError private val _searchContent: MutableLiveData = MutableLiveData() - private val searchContent: LiveData = _searchContent + val searchContent: LiveData = _searchContent private val _searchClearVisibility: MutableLiveData = MutableLiveData() val searchClearVisibility: LiveData get() = _searchClearVisibility diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 40eb212a..9886954c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -134,4 +134,5 @@ 검색어를 입력하세요. 검색 결과를 찾을 수 없어요 다른 키워드로 검색해보세요. + 2글자 이상 입력해야 합니다. \ No newline at end of file From 07848f6f82aeb7db94059b45264edaa125d4b752 Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Tue, 2 Apr 2024 21:22:17 +0900 Subject: [PATCH 3/7] =?UTF-8?q?design=20:=20=EC=8A=A4=ED=94=8C=EB=9E=98?= =?UTF-8?q?=EC=8B=9C=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/drawable/ic_symbol.xml | 62 ++++++++++++++------- app/src/main/res/layout/activity_splash.xml | 22 +++----- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/app/src/main/res/drawable/ic_symbol.xml b/app/src/main/res/drawable/ic_symbol.xml index a116cd8c..a2735655 100644 --- a/app/src/main/res/drawable/ic_symbol.xml +++ b/app/src/main/res/drawable/ic_symbol.xml @@ -1,26 +1,46 @@ + android:width="100dp" + android:height="113dp" + android:viewportWidth="100" + android:viewportHeight="113"> + + + - - - - - - + android:pathData="M0,97.33h100v14.71h-100z"/> + + + + + + diff --git a/app/src/main/res/layout/activity_splash.xml b/app/src/main/res/layout/activity_splash.xml index 54180615..b85b6d3c 100644 --- a/app/src/main/res/layout/activity_splash.xml +++ b/app/src/main/res/layout/activity_splash.xml @@ -1,29 +1,21 @@ - + - - - + app:layout_constraintTop_toTopOf="parent" /> \ No newline at end of file From 26b360f07a3dc5f372289019b5eafc62ca1eedd8 Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Tue, 2 Apr 2024 21:38:45 +0900 Subject: [PATCH 4/7] =?UTF-8?q?refactor=20:=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/youdongknowme/ui/view/search/SearchFragment.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt index 75a4fb3b..7343dad5 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt @@ -138,7 +138,7 @@ class SearchFragment : BaseFragment() { } private fun validateSearchContentLength(): Boolean { - return searchContent.length >= 2 + return searchContent.length >= SEARCH_CONTENT_MINIMUM_LENGTH } private fun navigateToDetail(url: String) { @@ -161,4 +161,8 @@ class SearchFragment : BaseFragment() { } }) } + + companion object { + private const val SEARCH_CONTENT_MINIMUM_LENGTH = 2 + } } \ No newline at end of file From a0b28d5f9ce5ba20066755df65d61df06f449d07 Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Tue, 2 Apr 2024 21:58:17 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat=20:=20=ED=82=A4=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EC=82=AC=EC=9D=B4=ED=81=B4=EB=9F=AC=EB=B7=B0=20?= =?UTF-8?q?=EC=98=81=EC=97=AD=20=EC=84=A0=ED=83=9D=20=EC=8B=9C=20=EB=82=B4?= =?UTF-8?q?=EB=A0=A4=EA=B0=80=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../youdongknowme/standard/util/UtilExt.kt | 19 +++++++++++--- .../ui/view/search/SearchFragment.kt | 26 +++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/standard/util/UtilExt.kt b/app/src/main/java/com/dongyang/android/youdongknowme/standard/util/UtilExt.kt index fdd613d4..b55c6585 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/standard/util/UtilExt.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/standard/util/UtilExt.kt @@ -1,20 +1,31 @@ package com.dongyang.android.youdongknowme.standard.util import android.app.Activity -import android.util.Log +import android.content.Context import android.view.View import android.view.inputmethod.InputMethodManager fun View.showKeyboard(isForced: Boolean = false) { - val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager - inputMethodManager.showSoftInput(this, if (isForced) InputMethodManager.SHOW_FORCED else InputMethodManager.SHOW_IMPLICIT) + val inputMethodManager = + context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.showSoftInput( + this, + if (isForced) InputMethodManager.SHOW_FORCED else InputMethodManager.SHOW_IMPLICIT + ) } fun View.hideKeyboard() { - val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + val inputMethodManager = + context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager inputMethodManager.hideSoftInputFromWindow(windowToken, 0) } +fun Int.dpToPx(context: Context): Int { + val density = context.resources.displayMetrics.density + return (this * density).toInt() +} + + object ACTION { const val FCM_ACTION_NAME = "com.google.firebase.MESSAGING_EVENT" } \ No newline at end of file diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt index 7343dad5..a85deda3 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.text.Editable import android.text.TextWatcher import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager @@ -11,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView import com.dongyang.android.youdongknowme.R import com.dongyang.android.youdongknowme.databinding.FragmentSearchBinding import com.dongyang.android.youdongknowme.standard.base.BaseFragment +import com.dongyang.android.youdongknowme.standard.util.dpToPx import com.dongyang.android.youdongknowme.ui.adapter.NoticeAdapter import com.dongyang.android.youdongknowme.ui.view.detail.DetailActivity import com.dongyang.android.youdongknowme.ui.view.util.EventObserver @@ -27,6 +29,7 @@ class SearchFragment : BaseFragment() { private var searchContent: String = "" override fun initStartView() { + setupRecyclerViewMargin() setupRecyclerview() showKeyboardOnEditTextFocus() setupHideKeyboardOnOutsideTouch() @@ -44,7 +47,12 @@ class SearchFragment : BaseFragment() { viewModel.searchNotices.observe(viewLifecycleOwner) { searchNotices -> if (searchNotices.isNotEmpty()) { + setupRecyclerViewMargin() adapter.submitList(searchNotices) + + } + if (searchNotices.isNullOrEmpty()) { + setupRecyclerViewMargin() } } @@ -67,6 +75,22 @@ class SearchFragment : BaseFragment() { override fun initAfterBinding() = Unit + private fun setupRecyclerViewMargin() { + if (::adapter.isInitialized.not()) { + val marginDp = SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_FOR_TOUCH + val marginPx = marginDp.dpToPx(requireContext()) + val layoutParams = binding.rvSearchResult.layoutParams as ViewGroup.MarginLayoutParams + layoutParams.topMargin = marginPx + binding.rvSearchResult.layoutParams = layoutParams + } else { + val marginDp = SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_DEFAULT + val marginPx = marginDp.dpToPx(requireContext()) + val layoutParams = binding.rvSearchResult.layoutParams as ViewGroup.MarginLayoutParams + layoutParams.topMargin = marginPx + binding.rvSearchResult.layoutParams = layoutParams + } + } + private fun setupRecyclerview() { adapter = NoticeAdapter(onItemClick = { url -> navigateToDetail(url) }) binding.rvSearchResult.apply { @@ -163,6 +187,8 @@ class SearchFragment : BaseFragment() { } companion object { + private const val SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_DEFAULT = 8 + private const val SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_FOR_TOUCH = 800 private const val SEARCH_CONTENT_MINIMUM_LENGTH = 2 } } \ No newline at end of file From 985c78fda234d522a9147166617401f098657fa5 Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Tue, 2 Apr 2024 22:42:47 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat=20:=20=EB=82=A0=EC=A7=9C=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20yyyy.mm.dd=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/youdongknowme/ui/viewholder/NoticeViewHodler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/viewholder/NoticeViewHodler.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/viewholder/NoticeViewHodler.kt index 88d8e919..14fa8b74 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/viewholder/NoticeViewHodler.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/viewholder/NoticeViewHodler.kt @@ -22,7 +22,7 @@ class NoticeViewHolder( noticeUrl = item.url binding.tvNoticeTitle.text = item.title - binding.tvNoticeDate.text = item.date + binding.tvNoticeDate.text = item.date.replace("-", ".") binding.tvNoticeAuthor.text = item.author } } \ No newline at end of file From 20de40d41b195d30c468745020b96598230bae8a Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Tue, 2 Apr 2024 23:26:22 +0900 Subject: [PATCH 7/7] =?UTF-8?q?design=20:=20=EB=A6=AC=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=ED=81=B4=EB=9F=AC=EB=B7=B0=20=EA=B5=AC=EB=B6=84=EC=84=A0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/youdongknowme/ui/view/notice/NoticeFragment.kt | 1 - .../android/youdongknowme/ui/view/search/SearchFragment.kt | 5 ----- app/src/main/res/layout/item_notice.xml | 1 - 3 files changed, 7 deletions(-) diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/notice/NoticeFragment.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/notice/NoticeFragment.kt index e43de5e4..2c36a752 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/notice/NoticeFragment.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/notice/NoticeFragment.kt @@ -26,7 +26,6 @@ class NoticeFragment : BaseFragment() { this.layoutManager = LinearLayoutManager(requireActivity()) this.itemAnimator = null this.setHasFixedSize(true) - this.addItemDecoration(DividerItemDecoration(requireContext(), 1)) } setupTabLayout() setupInfinityScroll() diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt index a85deda3..3b2333e6 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/search/SearchFragment.kt @@ -98,11 +98,6 @@ class SearchFragment : BaseFragment() { layoutManager = LinearLayoutManager(requireActivity()) itemAnimator = null setHasFixedSize(true) - addItemDecoration( - DividerItemDecoration( - requireContext(), DividerItemDecoration.VERTICAL - ) - ) } } diff --git a/app/src/main/res/layout/item_notice.xml b/app/src/main/res/layout/item_notice.xml index 61981781..aefb2c60 100644 --- a/app/src/main/res/layout/item_notice.xml +++ b/app/src/main/res/layout/item_notice.xml @@ -7,7 +7,6 @@ android:id="@+id/cl_notice_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/selectableItemBackground" android:backgroundTint="@color/white">