From 793d4ee43f963935919f2ebf4b743e924c169e33 Mon Sep 17 00:00:00 2001 From: zuojincheng <lf_zuo@163.com> Date: 星期一, 31 三月 2025 09:59:20 +0800 Subject: [PATCH] feat(search): 新增用户搜索功能并优化用户体验 --- generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt | 114 +++++++++++++++++- generallibrary/src/main/res/layout/item_user_list.xml | 88 +++++++++++++- generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt | 10 + generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt | 69 ++++++++++ generallibrary/src/main/res/layout/fragment_card.xml | 1 generallibrary/src/main/res/values/colors.xml | 1 generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt | 11 + generallibrary/src/main/res/layout/activity_search_user_ge.xml | 7 + 8 files changed, 270 insertions(+), 31 deletions(-) diff --git a/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt b/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt index 806c03e..b89fecf 100644 --- a/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt +++ b/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt @@ -33,13 +33,21 @@ private fun initView() { binding?.homeNewCard?.setOnClickListener { - val intent = Intent(context, SearchUserActivity::class.java) + val intent = Intent(context, SearchUserActivity::class.java).apply { + putExtra("type", "newUser") + } startActivity(intent) } binding?.homeManage?.setOnClickListener { val intent = Intent(context, ManageListActivity::class.java) startActivity(intent) } + binding?.homeLossLL?.setOnClickListener { + val intent = Intent(context, SearchUserActivity::class.java).apply{ + putExtra("type", "loss") + } + startActivity(intent) + } } } diff --git a/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt b/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt index bab9b4d..58644fa 100644 --- a/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt +++ b/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt @@ -19,13 +19,16 @@ fun initView() { binding?.titleBar?.setOnItemclickListner(ClickType_LEFT_IMAGE) { this.finish() } binding?.tvCleanCard?.setOnClickListener { - var intent = Intent(this, ManagerReadActivity::class.java) - intent.putExtra("cardType", CardCommon.CLEAN_CARD_TYPE) + var intent = Intent(this, ManagerReadActivity::class.java).apply { + putExtra("cardType", CardCommon.CLEAN_CARD_TYPE) + } + startActivity(intent) } binding?.tvCheckCard?.setOnClickListener { - var intent = Intent(this, ManagerReadActivity::class.java) - intent.putExtra("cardType", CardCommon.CHECK_CARD) + var intent = Intent(this, ManagerReadActivity::class.java).apply { + putExtra("cardType", CardCommon.CHECK_CARD) + } startActivity(intent) } diff --git a/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt b/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt index a0c6974..b284cea 100644 --- a/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt +++ b/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt @@ -12,6 +12,8 @@ import com.dayu.general.view.SearchDialog import com.dayu.general.net.ApiManager import com.dayu.general.net.BaseResponse +import com.scwang.smart.refresh.layout.api.RefreshLayout +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener /** * @author: zuo @@ -23,6 +25,16 @@ var binding: ActivitySearchUserGeBinding? = null private var userAdapter: SearchListAdapter? = null var searchDialog: SearchDialog? = null + + // 鍒嗛〉鐩稿叧鍙橀噺 + private var currentPage = 1 + private val pageSize = 20 + private var hasMoreData = true + + // 淇濆瓨褰撳墠鎼滅储鏉′欢 + private var currentFarmerId = "" + private var currentFarmerName = "" + private var currentCardNumber = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -30,7 +42,7 @@ setContentView(binding?.root) initView() setupRecyclerView() - + setupRefreshLayout() } @@ -41,12 +53,17 @@ // 璁剧疆鎼滅储鐩戝惉鍣� searchDialog?.setOnSearchListener(object : SearchDialog.OnSearchListener { override fun onSearch(farmerId: String, farmerName: String, cardNumber: String) { - // 澶勭悊鎼滅储缁撴灉 - // 杩欓噷鍙槸绀轰緥锛屽疄闄呭簲鐢ㄤ腑鍙兘闇�瑕佽皟鐢ˋPI鎴栨煡璇㈡暟鎹簱 - val message = - "鎼滅储鏉′欢锛歕n鍐滄埛缂栧彿锛�$farmerId\n鍐滄埛鍚嶇О锛�$farmerName\n鍗″彿锛�$cardNumber" - // 鎵ц瀹為檯鐨勬悳绱㈤�昏緫 - searchUser(farmerId, farmerName, cardNumber) + // 淇濆瓨褰撳墠鎼滅储鏉′欢 + currentFarmerId = farmerId + currentFarmerName = farmerName + currentCardNumber = cardNumber + + // 閲嶇疆鍒嗛〉鐘舵�� + currentPage = 1 + hasMoreData = true + + // 鎵ц鎼滅储 + searchUser(farmerId, farmerName, cardNumber, true) } }) binding?.titleBar?.setOnItemclickListner(ClickType_RIGHT_IMAGE) { @@ -62,6 +79,42 @@ layoutManager = LinearLayoutManager(this@SearchUserActivity) adapter = userAdapter } + + // 璁剧疆鍒楄〃椤圭偣鍑讳簨浠� + userAdapter?.setOnItemClickListener { user -> + // 澶勭悊鐢ㄦ埛鐐瑰嚮浜嬩欢 + ToastUtil.show("宸查�夋嫨鐢ㄦ埛锛�${user.name}") + // 杩欓噷鍙互娣诲姞璺宠浆鍒扮敤鎴疯鎯呴〉闈㈢殑閫昏緫 + // val intent = Intent(this, UserDetailActivity::class.java) + // intent.putExtra("userId", user.id) + // startActivity(intent) + } + } + + private fun setupRefreshLayout() { + binding?.refreshLayout?.apply { + // 璁剧疆鍒锋柊鍜屽姞杞芥洿澶氱洃鍚櫒 + setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener { + override fun onRefresh(refreshLayout: RefreshLayout) { + // 閲嶇疆椤电爜骞跺埛鏂版暟鎹� + currentPage = 1 + hasMoreData = true + searchUser(currentFarmerId, currentFarmerName, currentCardNumber, true) + } + + override fun onLoadMore(refreshLayout: RefreshLayout) { + // 濡傛灉杩樻湁鏇村鏁版嵁锛屽姞杞戒笅涓�椤� + if (hasMoreData) { + currentPage++ + searchUser(currentFarmerId, currentFarmerName, currentCardNumber, false) + } else { + // 瀹屾垚鍔犺浇骞舵彁绀烘病鏈夋洿澶氭暟鎹� + refreshLayout.finishLoadMore(500, true, false) + ToastUtil.show("娌℃湁鏇村鏁版嵁浜�") + } + } + }) + } } /** @@ -73,8 +126,9 @@ * @param farmerId 鍐滄皯鐨勫敮涓�鏍囪瘑绗� * @param farmerName 鍐滄皯鐨勫鍚� * @param cardNumber 閾惰鍗″彿 + * @param isRefresh 鏄惁涓哄埛鏂版搷浣� */ - private fun searchUser(farmerId: String, farmerName: String, cardNumber: String) { + private fun searchUser(farmerId: String, farmerName: String, cardNumber: String, isRefresh: Boolean = true) { val map = mutableMapOf<String, Any>() if (farmerId.isNotEmpty()) { @@ -88,6 +142,10 @@ if (cardNumber.isNotEmpty()) { map["cardNum"] = cardNumber } + + // 娣诲姞鍒嗛〉鍙傛暟 + map["pageCurr"] = currentPage + map["pageSize"] = pageSize // 浣跨敤姝g‘鐨勭被鍨嬪弬鏁� ApiManager.getInstance().requestGetLoading( @@ -97,18 +155,38 @@ map, object : SubscriberListener<BaseResponse<SearchUserResult>>() { override fun onNext(t: BaseResponse<SearchUserResult>) { + // 瀹屾垚鍒锋柊鎴栧姞杞藉姩浣� + finishRefreshOrLoad(isRefresh) + if (t.success) { // 澶勭悊鎼滅储鎴愬姛鐨勬儏鍐� val result = t.content if (result != null) { // 澶勭悊鎼滅储缁撴灉 if (result.obj.isNotEmpty()) { - userAdapter?.setData(result.obj) + // 鏍规嵁鏄惁涓哄埛鏂版搷浣滃喅瀹氬浣曟洿鏂版暟鎹� + if (isRefresh) { + userAdapter?.setData(result.obj) + } else { + userAdapter?.addData(result.obj) + } + + // 鍒ゆ柇鏄惁杩樻湁鏇村鏁版嵁锛氭牴鎹綋鍓嶉〉鐮佸拰鎬婚〉鏁板垽鏂� + hasMoreData = currentPage < result.pageTotal } else { - ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛") + if (isRefresh) { + userAdapter?.setData(emptyList()) + ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛") + } else { + hasMoreData = false + ToastUtil.show("娌℃湁鏇村鏁版嵁浜�") + } } } else { - ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛") + if (isRefresh) { + userAdapter?.setData(emptyList()) + ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛") + } } } else { // 澶勭悊鎼滅储澶辫触鐨勬儏鍐� @@ -118,11 +196,25 @@ override fun onError(e: Throwable?) { super.onError(e) + // 瀹屾垚鍒锋柊鎴栧姞杞藉姩浣� + finishRefreshOrLoad(isRefresh) ToastUtil.show("鎼滅储澶辫触: ${e?.message ?: "鏈煡閿欒"}") } } ) } + + /** + * 瀹屾垚鍒锋柊鎴栧姞杞芥搷浣� + * @param isRefresh 鏄惁涓哄埛鏂版搷浣� + */ + private fun finishRefreshOrLoad(isRefresh: Boolean) { + if (isRefresh) { + binding?.refreshLayout?.finishRefresh(true) + } else { + binding?.refreshLayout?.finishLoadMore(true) + } + } /** * 澶勭悊鎼滅储缁撴灉 diff --git a/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt b/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt index debb5f1..d63f6ac 100644 --- a/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt +++ b/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt @@ -1,6 +1,7 @@ package com.dayu.general.adapter import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.dayu.general.bean.net.SearchUserResult @@ -14,11 +15,22 @@ class SearchListAdapter : RecyclerView.Adapter<SearchListAdapter.UserViewHolder>(){ private val userList = mutableListOf<SearchUserResult.UserInfo>() + private var onItemClickListener: ((SearchUserResult.UserInfo) -> Unit)? = null fun setData(users: List<SearchUserResult.UserInfo>) { userList.clear() userList.addAll(users) notifyDataSetChanged() + } + + fun addData(users: List<SearchUserResult.UserInfo>) { + val startPosition = userList.size + userList.addAll(users) + notifyItemRangeInserted(startPosition, users.size) + } + + fun setOnItemClickListener(listener: (SearchUserResult.UserInfo) -> Unit) { + this.onItemClickListener = listener } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder { @@ -35,14 +47,61 @@ inner class UserViewHolder(private val binding: ItemUserListBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(user: SearchUserResult.UserInfo) { + // 璁剧疆鏁版嵁鏄剧ず锛屾坊鍔犲垽绌哄鐞� binding.tvCardCount.text = "鍗℃暟閲忥細${user.cardCount ?: "0"}" - binding.tvFarmerId.text = "瀹㈡埛缂栧彿锛�${user.clientNum ?: ""}" - binding.tvIdCard.text = "韬唤璇侊細${user.idCard ?: ""}" - binding.tvName.text = "濮撳悕锛�${user.name ?: ""}" - binding.tvPhone.text = "鐢佃瘽锛�${user.phone ?: ""}" + binding.tvFarmerId.text = "瀹㈡埛缂栧彿锛�${user.clientNum ?: "鏃�"}" + binding.tvIdCard.text = "韬唤璇侊細${formatIdCard(user.idCard)}" + binding.tvName.text = "濮撳悕锛�${user.name ?: "鏈煡"}" + binding.tvPhone.text = "鐢佃瘽锛�${formatPhone(user.phone)}" + + // 娣诲姞鍦板潃淇℃伅鏄剧ず + user.address?.let { address -> + if (address.isNotEmpty()) { + binding.tvAddress.text = "鍦板潃锛�$address" + binding.tvAddress.visibility = View.VISIBLE + } else { + binding.tvAddress.visibility = View.GONE + } + } ?: run { + binding.tvAddress.visibility = View.GONE + } + + // 鏄剧ず鎿嶄綔鏃ユ湡 + user.operateDt?.let { date -> + if (date.isNotEmpty()) { + binding.tvOperateDate.text = "鎿嶄綔鏃ユ湡锛�$date" + binding.tvOperateDate.visibility = View.VISIBLE + } else { + binding.tvOperateDate.visibility = View.GONE + } + } ?: run { + binding.tvOperateDate.visibility = View.GONE + } binding.root.setOnClickListener { - // 鍙互鍦ㄦ澶勬坊鍔犵偣鍑讳簨浠讹紝渚嬪鏌ョ湅鐢ㄦ埛璇︽儏 + onItemClickListener?.invoke(user) + } + } + + // 鏍煎紡鍖栬韩浠借瘉鍙凤紝淇濇姢闅愮 + private fun formatIdCard(idCard: String?): String { + return if (!idCard.isNullOrEmpty() && idCard.length >= 18) { + val start = idCard.substring(0, 6) + val end = idCard.substring(idCard.length - 4) + "$start****$end" + } else { + idCard ?: "鏃�" + } + } + + // 鏍煎紡鍖栨墜鏈哄彿锛屼繚鎶ら殣绉� + private fun formatPhone(phone: String?): String { + return if (!phone.isNullOrEmpty() && phone.length >= 11) { + val start = phone.substring(0, 3) + val end = phone.substring(phone.length - 4) + "$start****$end" + } else { + phone ?: "鏃�" } } } diff --git a/generallibrary/src/main/res/layout/activity_search_user_ge.xml b/generallibrary/src/main/res/layout/activity_search_user_ge.xml index 307148e..85198ca 100644 --- a/generallibrary/src/main/res/layout/activity_search_user_ge.xml +++ b/generallibrary/src/main/res/layout/activity_search_user_ge.xml @@ -23,11 +23,16 @@ android:layout_height="match_parent" android:layout_below="@+id/titleBar"> + <com.scwang.smart.refresh.header.ClassicsHeader + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" + android:layout_height="match_parent" - android:background="#ffffff" + android:background="@color/base_list_bg" android:overScrollMode="never" android:padding="10dp" /> diff --git a/generallibrary/src/main/res/layout/fragment_card.xml b/generallibrary/src/main/res/layout/fragment_card.xml index d09e603..338af60 100644 --- a/generallibrary/src/main/res/layout/fragment_card.xml +++ b/generallibrary/src/main/res/layout/fragment_card.xml @@ -161,6 +161,7 @@ app:layout_constraintTop_toBottomOf="@+id/home_newCard"> <LinearLayout + android:id="@+id/home_loss_LL" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" diff --git a/generallibrary/src/main/res/layout/item_user_list.xml b/generallibrary/src/main/res/layout/item_user_list.xml index e93821a..f2e4eab 100644 --- a/generallibrary/src/main/res/layout/item_user_list.xml +++ b/generallibrary/src/main/res/layout/item_user_list.xml @@ -1,13 +1,83 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.cardview.widget.CardView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:padding="12dp"> + android:layout_marginBottom="8dp" + app:cardCornerRadius="8dp" + app:cardElevation="2dp"> - <TextView android:id="@+id/tvCardCount" android:layout_width="match_parent" android:layout_height="wrap_content" /> - <TextView android:id="@+id/tvFarmerId" android:layout_width="match_parent" android:layout_height="wrap_content" /> - <TextView android:id="@+id/tvIdCard" android:layout_width="match_parent" android:layout_height="wrap_content" /> - <TextView android:id="@+id/tvName" android:layout_width="match_parent" android:layout_height="wrap_content" /> - <TextView android:id="@+id/tvPhone" android:layout_width="match_parent" android:layout_height="wrap_content" /> -</LinearLayout> \ No newline at end of file + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp"> + + <TextView + android:id="@+id/tvName" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:textStyle="bold" + android:textColor="#333333" + android:layout_marginBottom="8dp"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <TextView + android:id="@+id/tvFarmerId" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textColor="#666666" + android:layout_marginBottom="4dp"/> + + <TextView + android:id="@+id/tvCardCount" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textColor="#4CAF50" + android:layout_marginBottom="4dp"/> + </LinearLayout> + + <TextView + android:id="@+id/tvIdCard" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textColor="#666666" + android:layout_marginBottom="4dp"/> + + <TextView + android:id="@+id/tvPhone" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textColor="#666666" + android:layout_marginBottom="4dp"/> + + <TextView + android:id="@+id/tvAddress" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textColor="#666666" + android:layout_marginBottom="4dp" + android:visibility="gone"/> + + <TextView + android:id="@+id/tvOperateDate" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="12sp" + android:textColor="#999999" + android:layout_marginTop="4dp" + android:visibility="gone"/> + </LinearLayout> +</androidx.cardview.widget.CardView> \ No newline at end of file diff --git a/generallibrary/src/main/res/values/colors.xml b/generallibrary/src/main/res/values/colors.xml index f6ccfac..5729a42 100644 --- a/generallibrary/src/main/res/values/colors.xml +++ b/generallibrary/src/main/res/values/colors.xml @@ -4,5 +4,6 @@ <color name="black">#333</color> <color name="white">#fff</color> <color name="nav_item_color">#555555</color> + <color name="base_list_bg">#e6e6e6</color> </resources> \ No newline at end of file -- Gitblit v1.8.0