فهرست منبع

feat: 搜索列表去重,支持上下拉

DoggyZhang 1 ماه پیش
والد
کامیت
0724bf37ca

+ 20 - 0
module/profile/src/main/java/com/adealink/weparty/profile/search/SearchActivity.kt

@@ -47,6 +47,8 @@ import com.adealink.weparty.profile.search.viewmodel.SearchViewModel
 import com.adealink.weparty.util.applyImmersive
 import com.qmuiteam.qmui.widget.util.QMUIKeyboardHelper
 import com.qmuiteam.qmui.widget.util.QMUIStatusBarHelper
+import com.scwang.smart.refresh.layout.api.RefreshLayout
+import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
 import com.adealink.weparty.R as APP_R
 
 @RouterUri(
@@ -124,6 +126,20 @@ class SearchActivity : BaseActivity(),
         )
         binding.rvHistory.adapter = historyAdapter
 
+        binding.vRefresh.setEnableRefresh(true)
+        binding.vRefresh.setEnableLoadMore(false)
+        binding.vRefresh.setEnableAutoLoadMore(true)
+        binding.vRefresh.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
+            override fun onRefresh(refreshLayout: RefreshLayout) {
+                searchViewModel.reSearch()
+            }
+
+
+            override fun onLoadMore(refreshLayout: RefreshLayout) {
+                searchViewModel.searchMore()
+            }
+        })
+
         resultAdapter.register(SearchItemViewBinder(this))
         binding.rvResult.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
         binding.rvResult.adapter = resultAdapter
@@ -262,6 +278,10 @@ class SearchActivity : BaseActivity(),
             }
         }
         searchViewModel.searchRltLD.observeWithoutCache(this) { rlt ->
+            binding.vRefresh.finishRefresh()
+            binding.vRefresh.finishLoadMore()
+            binding.vRefresh.setEnableLoadMore(searchViewModel.hasMoreData())
+
             isSearching.postValue(false)
             when (rlt) {
                 is Rlt.Failed -> {

+ 33 - 7
module/profile/src/main/java/com/adealink/weparty/profile/search/viewmodel/SearchViewModel.kt

@@ -19,26 +19,39 @@ class SearchViewModel : BaseViewModel() {
         App.instance.networkService.getHttpService(SearchHttpService::class.java)
     }
 
+    val searchResultSet = mutableSetOf<String>()
     val searchResultLD = ExtMutableLiveData<List<SearchResultItemData>>()
     val searchRltLD = ExtMutableLiveData<Rlt<Any>>()
     private val searchResultList = mutableListOf<SearchResultItemData>()
     private val pageHandler = PageHandler()
     private var keyword: String? = null
-
-    fun search(keyword: String) {
+    fun search(keyword: String?) {
         pageHandler.reset()
         this.keyword = keyword
+        searchResultSet.clear()
         searchResultList.clear()
-        searchMore()
+        searchMore(keyword)
+    }
+
+    fun reSearch() {
+        search(keyword)
+    }
+
+    fun hasMoreData(): Boolean {
+        return !pageHandler.isEnd
     }
 
-    fun searchMore() {
+    fun searchMore(keyword: String? = this@SearchViewModel.keyword) {
         if (pageHandler.isEnd) {
             searchRltLD.send(Rlt.Failed(NoMoreDataError()))
             return
         }
         viewModelScope.launch {
-            val keyword = this@SearchViewModel.keyword ?: return@launch
+            if (keyword.isNullOrEmpty()) {
+                searchRltLD.send(Rlt.Success(Any()))
+                searchResultLD.send(emptyList())
+                return@launch
+            }
             val rlt = searchHttpService.search(
                 SearchReq(
                     keyword = keyword,
@@ -47,18 +60,31 @@ class SearchViewModel : BaseViewModel() {
             )
             when (rlt) {
                 is Rlt.Failed -> {
+                    if (keyword != this@SearchViewModel.keyword) {
+                        return@launch
+                    }
                     searchRltLD.send(rlt)
                 }
 
                 is Rlt.Success -> {
+                    if (keyword != this@SearchViewModel.keyword) {
+                        return@launch
+                    }
                     pageHandler.nextPage(rlt.data.data?.next)
-                    searchResultList.addAll(rlt.data.data?.list?.map {
+
+                    val nextList = rlt.data.data?.list?.filter {
+                        !searchResultSet.contains(it.uid)
+                    } ?: emptyList()
+
+                    val nextItemList = nextList.map {
                         it.online?.let { online ->
                             ProfileModule.updateUserOnline(it.uid, online)
                         }
 
                         SearchResultItemData(it)
-                    } ?: emptyList())
+                    }
+                    searchResultSet.addAll(nextList.map { it.uid })
+                    searchResultList.addAll(nextItemList)
                     searchRltLD.send(rlt)
                     searchResultLD.send(searchResultList)
                 }

+ 12 - 5
module/profile/src/main/res/layout/activity_user_search.xml

@@ -163,17 +163,24 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
 
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/rv_result"
-            style="@style/CommonVerticalFade"
+        <com.scwang.smart.refresh.layout.SmartRefreshLayout
+            android:id="@+id/v_refresh"
             android:layout_width="0dp"
             android:layout_height="0dp"
             android:layout_marginTop="10dp"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/tv_contact"
-            tools:listitem="@layout/layout_profile_search_item" />
+            app:layout_constraintTop_toBottomOf="@id/tv_contact">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/rv_result"
+                style="@style/CommonVerticalFade"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                tools:listitem="@layout/layout_profile_search_item" />
+
+        </com.scwang.smart.refresh.layout.SmartRefreshLayout>
 
         <com.adealink.weparty.commonui.widget.CommonEmptyErrorView
             android:id="@+id/v_error_view"