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/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 f21aba5f..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 @@ -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 @@ -24,8 +26,10 @@ class SearchFragment : BaseFragment() { override val viewModel: SearchViewModel by viewModel() private lateinit var adapter: NoticeAdapter + private var searchContent: String = "" override fun initStartView() { + setupRecyclerViewMargin() setupRecyclerview() showKeyboardOnEditTextFocus() setupHideKeyboardOnOutsideTouch() @@ -43,17 +47,50 @@ class SearchFragment : BaseFragment() { viewModel.searchNotices.observe(viewLifecycleOwner) { searchNotices -> if (searchNotices.isNotEmpty()) { + setupRecyclerViewMargin() adapter.submitList(searchNotices) + + } + if (searchNotices.isNullOrEmpty()) { + setupRecyclerViewMargin() } } + viewModel.searchContent.observe(viewLifecycleOwner) { content -> + searchContent = content + } + 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 + 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 { @@ -61,11 +98,6 @@ class SearchFragment : BaseFragment() { layoutManager = LinearLayoutManager(requireActivity()) itemAnimator = null setHasFixedSize(true) - addItemDecoration( - DividerItemDecoration( - requireContext(), DividerItemDecoration.VERTICAL - ) - ) } } @@ -109,7 +141,13 @@ class SearchFragment : BaseFragment() { private fun onSearchBtnClickListener() { binding.etSearchBar.setOnEditorActionListener { v, actionId, event -> if (actionId == EditorInfo.IME_ACTION_SEARCH) { - viewModel.fetchSearchNotices() + if (validateSearchContentLength()) { + viewModel.fetchSearchNotices() + adapter.submitList(emptyList()) + } else { + binding.etSearchBar.text.clear() + showToast(getString(R.string.search_minimum)) + } requireContext().hideKeyboard(binding.root) true } else { @@ -118,6 +156,10 @@ class SearchFragment : BaseFragment() { } } + private fun validateSearchContentLength(): Boolean { + return searchContent.length >= SEARCH_CONTENT_MINIMUM_LENGTH + } + private fun navigateToDetail(url: String) { val intent = DetailActivity.newIntent(requireContext(), url) startActivity(intent) @@ -138,4 +180,10 @@ 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 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..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 @@ -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/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 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/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 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/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"> 검색어를 입력하세요. + 검색 결과를 찾을 수 없어요 + 다른 키워드로 검색해보세요. + 2글자 이상 입력해야 합니다. \ No newline at end of file